lighting_client.c 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375
  1. /*
  2. * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <string.h>
  7. #include <errno.h>
  8. #include "btc_ble_mesh_lighting_model.h"
  9. #include "mesh/config.h"
  10. #include "mesh/model_opcode.h"
  11. #if CONFIG_BLE_MESH_LIGHTING_CLIENT
  12. #include "mesh/lighting_client.h"
  13. /* The followings are the macro definitions of Lighting client
  14. * model message length, and a message is composed of 3 parts:
  15. * Opcode + Payload + MIC
  16. */
  17. /* Light lightness client messages length */
  18. #define BLE_MESH_LIGHT_LIGHTNESS_GET_MSG_LEN (2 + 0 + 4)
  19. #define BLE_MESH_LIGHT_LIGHTNESS_SET_MSG_LEN (2 + 5 + 4)
  20. #define BLE_MESH_LIGHT_LIGHTNESS_LINEAR_GET_MSG_LEN (2 + 0 + 4)
  21. #define BLE_MESH_LIGHT_LIGHTNESS_LINEAR_SET_MSG_LEN (2 + 5 + 4)
  22. #define BLE_MESH_LIGHT_LIGHTNESS_LAST_GET_MSG_LEN (2 + 0 + 4)
  23. #define BLE_MESH_LIGHT_LIGHTNESS_DEFAULT_GET_MSG_LEN (2 + 0 + 4)
  24. #define BLE_MESH_LIGHT_LIGHTNESS_DEFAULT_SET_MSG_LEN (2 + 2 + 4)
  25. #define BLE_MESH_LIGHT_LIGHTNESS_RANGE_GET_MSG_LEN (2 + 0 + 4)
  26. #define BLE_MESH_LIGHT_LIGHTNESS_RANGE_SET_MSG_LEN (2 + 4 + 4)
  27. /* Light CTL client messages length */
  28. #define BLE_MESH_LIGHT_CTL_GET_MSG_LEN (2 + 0 + 4)
  29. #define BLE_MESH_LIGHT_CTL_SET_MSG_LEN (2 + 9 + 4)
  30. #define BLE_MESH_LIGHT_CTL_TEMPERATURE_GET_MSG_LEN (2 + 0 + 4)
  31. #define BLE_MESH_LIGHT_CTL_TEMPERATURE_SET_MSG_LEN (2 + 7 + 4)
  32. #define BLE_MESH_LIGHT_CTL_TEMPERATURE_RANGE_GET_MSG_LEN (2 + 0 + 4)
  33. #define BLE_MESH_LIGHT_CTL_TEMPERATURE_RANGE_SET_MSG_LEN (2 + 4 + 4)
  34. #define BLE_MESH_LIGHT_CTL_DEFAULT_GET_MSG_LEN (2 + 0 + 4)
  35. #define BLE_MESH_LIGHT_CTL_DEFAULT_SET_MSG_LEN (2 + 6 + 4)
  36. /* Light HSL client messages length */
  37. #define BLE_MESH_LIGHT_HSL_GET_MSG_LEN (2 + 0 + 4)
  38. #define BLE_MESH_LIGHT_HSL_SET_MSG_LEN (2 + 9 + 4)
  39. #define BLE_MESH_LIGHT_HSL_TARGET_GET_MSG_LEN (2 + 0 + 4)
  40. #define BLE_MESH_LIGHT_HSL_HUE_GET_MSG_LEN (2 + 0 + 4)
  41. #define BLE_MESH_LIGHT_HSL_HUE_SET_MSG_LEN (2 + 5 + 4)
  42. #define BLE_MESH_LIGHT_HSL_SATURATION_GET_MSG_LEN (2 + 0 + 4)
  43. #define BLE_MESH_LIGHT_HSL_SATURATION_SET_MSG_LEN (2 + 5 + 4)
  44. #define BLE_MESH_LIGHT_HSL_DEFAULT_GET_MSG_LEN (2 + 0 + 4)
  45. #define BLE_MESH_LIGHT_HSL_DEFAULT_SET_MSG_LEN (2 + 6 + 4)
  46. #define BLE_MESH_LIGHT_HSL_RANGE_GET_MSG_LEN (2 + 0 + 4)
  47. #define BLE_MESH_LIGHT_HSL_RANGE_SET_MSG_LEN (2 + 8 + 4)
  48. /* Light xyL client messages length */
  49. #define BLE_MESH_LIGHT_XYL_SET_MSG_LEN (2 + 9 + 4)
  50. #define BLE_MESH_LIGHT_XYL_DEFAULT_SET_MSG_LEN (2 + 6 + 4)
  51. #define BLE_MESH_LIGHT_XYL_RANGE_SET_MSG_LEN (2 + 8 + 4)
  52. /* Light LC client messages length */
  53. #define BLE_MESH_LIGHT_LC_MODE_SET_MSG_LEN (2 + 1 + 4)
  54. #define BLE_MESH_LIGHT_LC_OM_SET_MSG_LEN (2 + 1 + 4)
  55. #define BLE_MESH_LIGHT_LC_LIGHT_ONOFF_SET_MSG_LEN (2 + 4 + 4)
  56. #define BLE_MESH_LIGHT_LC_PROPERTY_GET_MSG_LEN (2 + 2 + 4)
  57. #define BLE_MESH_LIGHT_LC_PROPERTY_SET_MSG_LEN /* variable */
  58. #define BLE_MESH_LIGHT_GET_STATE_MSG_LEN (2 + 2 + 4)
  59. static const bt_mesh_client_op_pair_t light_op_pair[] = {
  60. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS },
  61. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS },
  62. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS },
  63. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS },
  64. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS },
  65. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS },
  66. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS },
  67. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS },
  68. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET, BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS },
  69. { BLE_MESH_MODEL_OP_LIGHT_CTL_GET, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS },
  70. { BLE_MESH_MODEL_OP_LIGHT_CTL_SET, BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS },
  71. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS },
  72. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS },
  73. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS },
  74. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET, BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS },
  75. { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET, BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS },
  76. { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET, BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS },
  77. { BLE_MESH_MODEL_OP_LIGHT_HSL_GET, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS },
  78. { BLE_MESH_MODEL_OP_LIGHT_HSL_SET, BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS },
  79. { BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET, BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS },
  80. { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS },
  81. { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET, BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS },
  82. { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS },
  83. { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET, BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS },
  84. { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET, BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS },
  85. { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET, BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS },
  86. { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS },
  87. { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET, BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS },
  88. { BLE_MESH_MODEL_OP_LIGHT_XYL_GET, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS },
  89. { BLE_MESH_MODEL_OP_LIGHT_XYL_SET, BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS },
  90. { BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET, BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS },
  91. { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET, BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS },
  92. { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET, BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS },
  93. { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET, BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS },
  94. { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET, BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS },
  95. { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET, BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS },
  96. { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET, BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS },
  97. { BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET, BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS },
  98. { BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET, BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS },
  99. { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS },
  100. { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET, BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS },
  101. { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET, BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS },
  102. { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET, BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS },
  103. };
  104. static bt_mesh_mutex_t lighting_client_lock;
  105. static void timeout_handler(struct k_work *work)
  106. {
  107. struct k_delayed_work *timer = NULL;
  108. bt_mesh_client_node_t *node = NULL;
  109. struct bt_mesh_model *model = NULL;
  110. struct bt_mesh_msg_ctx ctx = {0};
  111. uint32_t opcode = 0U;
  112. BT_WARN("Receive light status message timeout");
  113. bt_mesh_mutex_lock(&lighting_client_lock);
  114. timer = CONTAINER_OF(work, struct k_delayed_work, work);
  115. if (timer && !k_delayed_work_free(timer)) {
  116. node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
  117. if (node) {
  118. memcpy(&ctx, &node->ctx, sizeof(ctx));
  119. opcode = node->opcode;
  120. model = node->model;
  121. bt_mesh_client_free_node(node);
  122. bt_mesh_lighting_client_cb_evt_to_btc(
  123. opcode, BTC_BLE_MESH_EVT_LIGHTING_CLIENT_TIMEOUT, model, &ctx, NULL, 0);
  124. }
  125. }
  126. bt_mesh_mutex_unlock(&lighting_client_lock);
  127. }
  128. static void light_status(struct bt_mesh_model *model,
  129. struct bt_mesh_msg_ctx *ctx,
  130. struct net_buf_simple *buf)
  131. {
  132. bt_mesh_client_node_t *node = NULL;
  133. uint8_t *val = NULL;
  134. uint8_t evt = 0xFF;
  135. size_t len = 0U;
  136. BT_DBG("len %d, bytes %s", buf->len, bt_hex(buf->data, buf->len));
  137. switch (ctx->recv_op) {
  138. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS: {
  139. struct bt_mesh_light_lightness_status *status = NULL;
  140. if (buf->len != 2 && buf->len != 5) {
  141. BT_ERR("Invalid Light Lightness Status length %d", buf->len);
  142. return;
  143. }
  144. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_status));
  145. if (!status) {
  146. BT_ERR("%s, Out of memory", __func__);
  147. return;
  148. }
  149. status->present_lightness = net_buf_simple_pull_le16(buf);
  150. if (buf->len) {
  151. status->op_en = true;
  152. status->target_lightness = net_buf_simple_pull_le16(buf);
  153. status->remain_time = net_buf_simple_pull_u8(buf);
  154. }
  155. val = (uint8_t *)status;
  156. len = sizeof(struct bt_mesh_light_lightness_status);
  157. break;
  158. }
  159. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS: {
  160. struct bt_mesh_light_lightness_linear_status *status = NULL;
  161. if (buf->len != 2 && buf->len != 5) {
  162. BT_ERR("Invalid Light Lightness Linear Status length %d", buf->len);
  163. return;
  164. }
  165. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_linear_status));
  166. if (!status) {
  167. BT_ERR("%s, Out of memory", __func__);
  168. return;
  169. }
  170. status->present_lightness = net_buf_simple_pull_le16(buf);
  171. if (buf->len) {
  172. status->op_en = true;
  173. status->target_lightness = net_buf_simple_pull_le16(buf);
  174. status->remain_time = net_buf_simple_pull_u8(buf);
  175. }
  176. val = (uint8_t *)status;
  177. len = sizeof(struct bt_mesh_light_lightness_linear_status);
  178. break;
  179. }
  180. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS: {
  181. struct bt_mesh_light_lightness_last_status *status = NULL;
  182. if (buf->len != 2) {
  183. BT_ERR("Invalid Light Lightness Last Status length %d", buf->len);
  184. return;
  185. }
  186. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_last_status));
  187. if (!status) {
  188. BT_ERR("%s, Out of memory", __func__);
  189. return;
  190. }
  191. status->lightness = net_buf_simple_pull_le16(buf);
  192. val = (uint8_t *)status;
  193. len = sizeof(struct bt_mesh_light_lightness_last_status);
  194. break;
  195. }
  196. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS: {
  197. struct bt_mesh_light_lightness_default_status *status = NULL;
  198. if (buf->len != 2) {
  199. BT_ERR("Invalid Light Lightness Default Status length %d", buf->len);
  200. return;
  201. }
  202. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_default_status));
  203. if (!status) {
  204. BT_ERR("%s, Out of memory", __func__);
  205. return;
  206. }
  207. status->lightness = net_buf_simple_pull_le16(buf);
  208. val = (uint8_t *)status;
  209. len = sizeof(struct bt_mesh_light_lightness_default_status);
  210. break;
  211. }
  212. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS: {
  213. struct bt_mesh_light_lightness_range_status *status = NULL;
  214. if (buf->len != 5) {
  215. BT_ERR("Invalid Light Lightness Range Status length %d", buf->len);
  216. return;
  217. }
  218. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lightness_range_status));
  219. if (!status) {
  220. BT_ERR("%s, Out of memory", __func__);
  221. return;
  222. }
  223. status->status_code = net_buf_simple_pull_u8(buf);
  224. status->range_min = net_buf_simple_pull_le16(buf);
  225. status->range_max = net_buf_simple_pull_le16(buf);
  226. val = (uint8_t *)status;
  227. len = sizeof(struct bt_mesh_light_lightness_range_status);
  228. break;
  229. }
  230. case BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS: {
  231. struct bt_mesh_light_ctl_status *status = NULL;
  232. if (buf->len != 4 && buf->len != 9) {
  233. BT_ERR("Invalid Light CTL Status length %d", buf->len);
  234. return;
  235. }
  236. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_status));
  237. if (!status) {
  238. BT_ERR("%s, Out of memory", __func__);
  239. return;
  240. }
  241. status->present_ctl_lightness = net_buf_simple_pull_le16(buf);
  242. status->present_ctl_temperature = net_buf_simple_pull_le16(buf);
  243. if (buf->len) {
  244. status->op_en = true;
  245. status->target_ctl_lightness = net_buf_simple_pull_le16(buf);
  246. status->target_ctl_temperature = net_buf_simple_pull_le16(buf);
  247. status->remain_time = net_buf_simple_pull_u8(buf);
  248. }
  249. val = (uint8_t *)status;
  250. len = sizeof(struct bt_mesh_light_ctl_status);
  251. break;
  252. }
  253. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS: {
  254. struct bt_mesh_light_ctl_temperature_status *status = NULL;
  255. if (buf->len != 4 && buf->len != 9) {
  256. BT_ERR("Invalid Light CTL Temperature Status length %d", buf->len);
  257. return;
  258. }
  259. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_temperature_status));
  260. if (!status) {
  261. BT_ERR("%s, Out of memory", __func__);
  262. return;
  263. }
  264. status->present_ctl_temperature = net_buf_simple_pull_le16(buf);
  265. status->present_ctl_delta_uv = net_buf_simple_pull_le16(buf);
  266. if (buf->len) {
  267. status->op_en = true;
  268. status->target_ctl_temperature = net_buf_simple_pull_le16(buf);
  269. status->target_ctl_delta_uv = net_buf_simple_pull_le16(buf);
  270. status->remain_time = net_buf_simple_pull_u8(buf);
  271. }
  272. val = (uint8_t *)status;
  273. len = sizeof(struct bt_mesh_light_ctl_temperature_status);
  274. break;
  275. }
  276. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS: {
  277. struct bt_mesh_light_ctl_temperature_range_status *status = NULL;
  278. if (buf->len != 5) {
  279. BT_ERR("Invalid Light CTL Temperature Range Status length %d", buf->len);
  280. return;
  281. }
  282. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_temperature_range_status));
  283. if (!status) {
  284. BT_ERR("%s, Out of memory", __func__);
  285. return;
  286. }
  287. status->status_code = net_buf_simple_pull_u8(buf);
  288. status->range_min = net_buf_simple_pull_le16(buf);
  289. status->range_max = net_buf_simple_pull_le16(buf);
  290. val = (uint8_t *)status;
  291. len = sizeof(struct bt_mesh_light_ctl_temperature_range_status);
  292. break;
  293. }
  294. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS: {
  295. struct bt_mesh_light_ctl_default_status *status = NULL;
  296. if (buf->len != 6) {
  297. BT_ERR("Invalid Light CTL Default Status length %d", buf->len);
  298. return;
  299. }
  300. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_ctl_default_status));
  301. if (!status) {
  302. BT_ERR("%s, Out of memory", __func__);
  303. return;
  304. }
  305. status->lightness = net_buf_simple_pull_le16(buf);
  306. status->temperature = net_buf_simple_pull_le16(buf);
  307. status->delta_uv = net_buf_simple_pull_le16(buf);
  308. val = (uint8_t *)status;
  309. len = sizeof(struct bt_mesh_light_ctl_default_status);
  310. break;
  311. }
  312. case BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS: {
  313. struct bt_mesh_light_hsl_status *status = NULL;
  314. if (buf->len != 6 && buf->len != 7) {
  315. BT_ERR("Invalid Light HSL Status length %d", buf->len);
  316. return;
  317. }
  318. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_status));
  319. if (!status) {
  320. BT_ERR("%s, Out of memory", __func__);
  321. return;
  322. }
  323. status->hsl_lightness = net_buf_simple_pull_le16(buf);
  324. status->hsl_hue = net_buf_simple_pull_le16(buf);
  325. status->hsl_saturation = net_buf_simple_pull_le16(buf);
  326. if (buf->len) {
  327. status->op_en = true;
  328. status->remain_time = net_buf_simple_pull_u8(buf);
  329. }
  330. val = (uint8_t *)status;
  331. len = sizeof(struct bt_mesh_light_hsl_status);
  332. break;
  333. }
  334. case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS: {
  335. struct bt_mesh_light_hsl_target_status *status = NULL;
  336. if (buf->len != 6 && buf->len != 7) {
  337. BT_ERR("Invalid Light HSL Target Status length %d", buf->len);
  338. return;
  339. }
  340. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_target_status));
  341. if (!status) {
  342. BT_ERR("%s, Out of memory", __func__);
  343. return;
  344. }
  345. status->hsl_lightness_target = net_buf_simple_pull_le16(buf);
  346. status->hsl_hue_target = net_buf_simple_pull_le16(buf);
  347. status->hsl_saturation_target = net_buf_simple_pull_le16(buf);
  348. if (buf->len) {
  349. status->op_en = true;
  350. status->remain_time = net_buf_simple_pull_u8(buf);
  351. }
  352. val = (uint8_t *)status;
  353. len = sizeof(struct bt_mesh_light_hsl_target_status);
  354. break;
  355. }
  356. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS: {
  357. struct bt_mesh_light_hsl_hue_status *status = NULL;
  358. if (buf->len != 2 && buf->len != 5) {
  359. BT_ERR("Invalid Light HSL Hue Status length %d", buf->len);
  360. return;
  361. }
  362. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_hue_status));
  363. if (!status) {
  364. BT_ERR("%s, Out of memory", __func__);
  365. return;
  366. }
  367. status->present_hue = net_buf_simple_pull_le16(buf);
  368. if (buf->len) {
  369. status->op_en = true;
  370. status->target_hue = net_buf_simple_pull_le16(buf);
  371. status->remain_time = net_buf_simple_pull_u8(buf);
  372. }
  373. val = (uint8_t *)status;
  374. len = sizeof(struct bt_mesh_light_hsl_hue_status);
  375. break;
  376. }
  377. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS: {
  378. struct bt_mesh_light_hsl_saturation_status *status = NULL;
  379. if (buf->len != 2 && buf->len != 5) {
  380. BT_ERR("Invalid Light HSL Saturation Status length %d", buf->len);
  381. return;
  382. }
  383. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_saturation_status));
  384. if (!status) {
  385. BT_ERR("%s, Out of memory", __func__);
  386. return;
  387. }
  388. status->present_saturation = net_buf_simple_pull_le16(buf);
  389. if (buf->len) {
  390. status->op_en = true;
  391. status->target_saturation = net_buf_simple_pull_le16(buf);
  392. status->remain_time = net_buf_simple_pull_u8(buf);
  393. }
  394. val = (uint8_t *)status;
  395. len = sizeof(struct bt_mesh_light_hsl_saturation_status);
  396. break;
  397. }
  398. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS: {
  399. struct bt_mesh_light_hsl_default_status *status = NULL;
  400. if (buf->len != 6) {
  401. BT_ERR("Invalid Light HSL Default Status length %d", buf->len);
  402. return;
  403. }
  404. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_default_status));
  405. if (!status) {
  406. BT_ERR("%s, Out of memory", __func__);
  407. return;
  408. }
  409. status->lightness = net_buf_simple_pull_le16(buf);
  410. status->hue = net_buf_simple_pull_le16(buf);
  411. status->saturation = net_buf_simple_pull_le16(buf);
  412. val = (uint8_t *)status;
  413. len = sizeof(struct bt_mesh_light_hsl_default_status);
  414. break;
  415. }
  416. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS: {
  417. struct bt_mesh_light_hsl_range_status *status = NULL;
  418. if (buf->len != 9) {
  419. BT_ERR("Invalid Light HSL Range Status length %d", buf->len);
  420. return;
  421. }
  422. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_hsl_range_status));
  423. if (!status) {
  424. BT_ERR("%s, Out of memory", __func__);
  425. return;
  426. }
  427. status->status_code = net_buf_simple_pull_u8(buf);
  428. status->hue_range_min = net_buf_simple_pull_le16(buf);
  429. status->hue_range_max = net_buf_simple_pull_le16(buf);
  430. status->saturation_range_min = net_buf_simple_pull_le16(buf);
  431. status->saturation_range_max = net_buf_simple_pull_le16(buf);
  432. val = (uint8_t *)status;
  433. len = sizeof(struct bt_mesh_light_hsl_range_status);
  434. break;
  435. }
  436. case BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS: {
  437. struct bt_mesh_light_xyl_status *status = NULL;
  438. if (buf->len != 6 && buf->len != 7) {
  439. BT_ERR("Invalid Light xyL Status length %d", buf->len);
  440. return;
  441. }
  442. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_status));
  443. if (!status) {
  444. BT_ERR("%s, Out of memory", __func__);
  445. return;
  446. }
  447. status->xyl_lightness = net_buf_simple_pull_le16(buf);
  448. status->xyl_x = net_buf_simple_pull_le16(buf);
  449. status->xyl_y = net_buf_simple_pull_le16(buf);
  450. if (buf->len) {
  451. status->op_en = true;
  452. status->remain_time = net_buf_simple_pull_u8(buf);
  453. }
  454. val = (uint8_t *)status;
  455. len = sizeof(struct bt_mesh_light_xyl_status);
  456. break;
  457. }
  458. case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS: {
  459. struct bt_mesh_light_xyl_target_status *status = NULL;
  460. if (buf->len != 6 && buf->len != 7) {
  461. BT_ERR("Invalid Light xyL Target Status length %d", buf->len);
  462. return;
  463. }
  464. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_target_status));
  465. if (!status) {
  466. BT_ERR("%s, Out of memory", __func__);
  467. return;
  468. }
  469. status->target_xyl_lightness = net_buf_simple_pull_le16(buf);
  470. status->target_xyl_x = net_buf_simple_pull_le16(buf);
  471. status->target_xyl_y = net_buf_simple_pull_le16(buf);
  472. if (buf->len) {
  473. status->op_en = true;
  474. status->remain_time = net_buf_simple_pull_u8(buf);
  475. }
  476. val = (uint8_t *)status;
  477. len = sizeof(struct bt_mesh_light_xyl_target_status);
  478. break;
  479. }
  480. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS: {
  481. struct bt_mesh_light_xyl_default_status *status = NULL;
  482. if (buf->len != 6) {
  483. BT_ERR("Invalid Light xyL Default Status length %d", buf->len);
  484. return;
  485. }
  486. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_default_status));
  487. if (!status) {
  488. BT_ERR("%s, Out of memory", __func__);
  489. return;
  490. }
  491. status->lightness = net_buf_simple_pull_le16(buf);
  492. status->xyl_x = net_buf_simple_pull_le16(buf);
  493. status->xyl_y = net_buf_simple_pull_le16(buf);
  494. val = (uint8_t *)status;
  495. len = sizeof(struct bt_mesh_light_xyl_default_status);
  496. break;
  497. }
  498. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS: {
  499. struct bt_mesh_light_xyl_range_status *status = NULL;
  500. if (buf->len != 9) {
  501. BT_ERR("Invalid Light xyL Range Status length %d", buf->len);
  502. return;
  503. }
  504. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_xyl_range_status));
  505. if (!status) {
  506. BT_ERR("%s, Out of memory", __func__);
  507. return;
  508. }
  509. status->status_code = net_buf_simple_pull_u8(buf);
  510. status->xyl_x_range_min = net_buf_simple_pull_le16(buf);
  511. status->xyl_x_range_max = net_buf_simple_pull_le16(buf);
  512. status->xyl_y_range_min = net_buf_simple_pull_le16(buf);
  513. status->xyl_y_range_max = net_buf_simple_pull_le16(buf);
  514. val = (uint8_t *)status;
  515. len = sizeof(struct bt_mesh_light_xyl_range_status);
  516. break;
  517. }
  518. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS: {
  519. struct bt_mesh_light_lc_mode_status *status = NULL;
  520. if (buf->len != 1) {
  521. BT_ERR("Invalid Light LC Mode Status length %d", buf->len);
  522. return;
  523. }
  524. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_mode_status));
  525. if (!status) {
  526. BT_ERR("%s, Out of memory", __func__);
  527. return;
  528. }
  529. status->mode = net_buf_simple_pull_u8(buf);
  530. val = (uint8_t *)status;
  531. len = sizeof(struct bt_mesh_light_lc_mode_status);
  532. break;
  533. }
  534. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS: {
  535. struct bt_mesh_light_lc_om_status *status = NULL;
  536. if (buf->len != 1) {
  537. BT_ERR("Invalid Light LC OM Status length %d", buf->len);
  538. return;
  539. }
  540. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_om_status));
  541. if (!status) {
  542. BT_ERR("%s, Out of memory", __func__);
  543. return;
  544. }
  545. status->mode = net_buf_simple_pull_u8(buf);
  546. val = (uint8_t *)status;
  547. len = sizeof(struct bt_mesh_light_lc_om_status);
  548. break;
  549. }
  550. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS: {
  551. struct bt_mesh_light_lc_light_onoff_status *status = NULL;
  552. if (buf->len != 1 && buf->len != 3) {
  553. BT_ERR("Invalid Light LC Light OnOff Status length %d", buf->len);
  554. return;
  555. }
  556. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_light_onoff_status));
  557. if (!status) {
  558. BT_ERR("%s, Out of memory", __func__);
  559. return;
  560. }
  561. status->present_light_onoff = net_buf_simple_pull_u8(buf);
  562. if (buf->len) {
  563. status->op_en = true;
  564. status->target_light_onoff = net_buf_simple_pull_u8(buf);
  565. status->remain_time = net_buf_simple_pull_u8(buf);
  566. }
  567. val = (uint8_t *)status;
  568. len = sizeof(struct bt_mesh_light_lc_light_onoff_status);
  569. break;
  570. }
  571. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS: {
  572. struct bt_mesh_light_lc_property_status *status = NULL;
  573. status = bt_mesh_calloc(sizeof(struct bt_mesh_light_lc_property_status));
  574. if (!status) {
  575. BT_ERR("%s, Out of memory", __func__);
  576. return;
  577. }
  578. status->light_lc_property_id = net_buf_simple_pull_le16(buf);
  579. status->light_lc_property_value = bt_mesh_alloc_buf(buf->len);
  580. if (!status->light_lc_property_value) {
  581. BT_ERR("%s, Out of memory", __func__);
  582. bt_mesh_free(status);
  583. return;
  584. }
  585. net_buf_simple_add_mem(status->light_lc_property_value, buf->data, buf->len);
  586. val = (uint8_t *)status;
  587. len = sizeof(struct bt_mesh_light_lc_property_status);
  588. break;
  589. }
  590. default:
  591. BT_ERR("Invalid Lighting Status opcode 0x%04x", ctx->recv_op);
  592. return;
  593. }
  594. buf->data = val;
  595. buf->len = len;
  596. bt_mesh_mutex_lock(&lighting_client_lock);
  597. node = bt_mesh_is_client_recv_publish_msg(model, ctx, buf, true);
  598. if (!node) {
  599. BT_DBG("Unexpected Lighting Status 0x%04x", ctx->recv_op);
  600. } else {
  601. switch (node->opcode) {
  602. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET:
  603. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET:
  604. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET:
  605. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET:
  606. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET:
  607. case BLE_MESH_MODEL_OP_LIGHT_CTL_GET:
  608. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET:
  609. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET:
  610. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET:
  611. case BLE_MESH_MODEL_OP_LIGHT_HSL_GET:
  612. case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET:
  613. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET:
  614. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET:
  615. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET:
  616. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET:
  617. case BLE_MESH_MODEL_OP_LIGHT_XYL_GET:
  618. case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET:
  619. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET:
  620. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET:
  621. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET:
  622. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET:
  623. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET:
  624. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET:
  625. evt = BTC_BLE_MESH_EVT_LIGHTING_CLIENT_GET_STATE;
  626. break;
  627. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET:
  628. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET:
  629. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET:
  630. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET:
  631. case BLE_MESH_MODEL_OP_LIGHT_CTL_SET:
  632. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET:
  633. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET:
  634. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET:
  635. case BLE_MESH_MODEL_OP_LIGHT_HSL_SET:
  636. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET:
  637. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET:
  638. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET:
  639. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET:
  640. case BLE_MESH_MODEL_OP_LIGHT_XYL_SET:
  641. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET:
  642. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET:
  643. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET:
  644. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET:
  645. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET:
  646. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
  647. evt = BTC_BLE_MESH_EVT_LIGHTING_CLIENT_SET_STATE;
  648. break;
  649. default:
  650. break;
  651. }
  652. if (!k_delayed_work_free(&node->timer)) {
  653. uint32_t opcode = node->opcode;
  654. bt_mesh_client_free_node(node);
  655. bt_mesh_lighting_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len);
  656. }
  657. }
  658. bt_mesh_mutex_unlock(&lighting_client_lock);
  659. switch (ctx->recv_op) {
  660. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS: {
  661. struct bt_mesh_light_lc_property_status *status;
  662. status = (struct bt_mesh_light_lc_property_status *)val;
  663. bt_mesh_free_buf(status->light_lc_property_value);
  664. break;
  665. }
  666. default:
  667. break;
  668. }
  669. bt_mesh_free(val);
  670. }
  671. const struct bt_mesh_model_op bt_mesh_light_lightness_cli_op[] = {
  672. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS, 2, light_status },
  673. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS, 2, light_status },
  674. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS, 2, light_status },
  675. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS, 2, light_status },
  676. { BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS, 5, light_status },
  677. BLE_MESH_MODEL_OP_END,
  678. };
  679. const struct bt_mesh_model_op bt_mesh_light_ctl_cli_op[] = {
  680. { BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS, 4, light_status },
  681. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS, 4, light_status },
  682. { BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS, 5, light_status },
  683. { BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS, 6, light_status },
  684. BLE_MESH_MODEL_OP_END,
  685. };
  686. const struct bt_mesh_model_op bt_mesh_light_hsl_cli_op[] = {
  687. { BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS, 6, light_status },
  688. { BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS, 6, light_status },
  689. { BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS, 2, light_status },
  690. { BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS, 2, light_status },
  691. { BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS, 6, light_status },
  692. { BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS, 9, light_status },
  693. BLE_MESH_MODEL_OP_END,
  694. };
  695. const struct bt_mesh_model_op bt_mesh_light_xyl_cli_op[] = {
  696. { BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS, 6, light_status },
  697. { BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS, 6, light_status },
  698. { BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS, 6, light_status },
  699. { BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS, 9, light_status },
  700. BLE_MESH_MODEL_OP_END,
  701. };
  702. const struct bt_mesh_model_op bt_mesh_light_lc_cli_op[] = {
  703. { BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS, 1, light_status },
  704. { BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS, 1, light_status },
  705. { BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS, 1, light_status },
  706. { BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS, 2, light_status },
  707. BLE_MESH_MODEL_OP_END,
  708. };
  709. static int light_get_state(bt_mesh_client_common_param_t *common, void *value)
  710. {
  711. NET_BUF_SIMPLE_DEFINE(msg, BLE_MESH_LIGHT_GET_STATE_MSG_LEN);
  712. bt_mesh_model_msg_init(&msg, common->opcode);
  713. if (value) {
  714. switch (common->opcode) {
  715. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET: {
  716. struct bt_mesh_light_lc_property_get *get;
  717. get = (struct bt_mesh_light_lc_property_get *)value;
  718. net_buf_simple_add_le16(&msg, get->light_lc_property_id);
  719. break;
  720. }
  721. default:
  722. BT_DBG("No parameters for Lighting Get 0x%04x", common->opcode);
  723. break;
  724. }
  725. }
  726. return bt_mesh_client_send_msg(common, &msg, true, timeout_handler);
  727. }
  728. static int light_set_state(bt_mesh_client_common_param_t *common,
  729. void *value, uint16_t value_len, bool need_ack)
  730. {
  731. struct net_buf_simple *msg = NULL;
  732. int err = 0;
  733. msg = bt_mesh_alloc_buf(value_len);
  734. if (!msg) {
  735. BT_ERR("%s, Out of memory", __func__);
  736. return -ENOMEM;
  737. }
  738. bt_mesh_model_msg_init(msg, common->opcode);
  739. switch (common->opcode) {
  740. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET:
  741. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK: {
  742. struct bt_mesh_light_lightness_set *set;
  743. set = (struct bt_mesh_light_lightness_set *)value;
  744. net_buf_simple_add_le16(msg, set->lightness);
  745. net_buf_simple_add_u8(msg, set->tid);
  746. if (set->op_en) {
  747. net_buf_simple_add_u8(msg, set->trans_time);
  748. net_buf_simple_add_u8(msg, set->delay);
  749. }
  750. break;
  751. }
  752. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET:
  753. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK: {
  754. struct bt_mesh_light_lightness_linear_set *set;
  755. set = (struct bt_mesh_light_lightness_linear_set *)value;
  756. net_buf_simple_add_le16(msg, set->lightness);
  757. net_buf_simple_add_u8(msg, set->tid);
  758. if (set->op_en) {
  759. net_buf_simple_add_u8(msg, set->trans_time);
  760. net_buf_simple_add_u8(msg, set->delay);
  761. }
  762. break;
  763. }
  764. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET:
  765. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK: {
  766. struct bt_mesh_light_lightness_default_set *set;
  767. set = (struct bt_mesh_light_lightness_default_set *)value;
  768. net_buf_simple_add_le16(msg, set->lightness);
  769. break;
  770. }
  771. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET:
  772. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK: {
  773. struct bt_mesh_light_lightness_range_set *set;
  774. set = (struct bt_mesh_light_lightness_range_set *)value;
  775. net_buf_simple_add_le16(msg, set->range_min);
  776. net_buf_simple_add_le16(msg, set->range_max);
  777. break;
  778. }
  779. case BLE_MESH_MODEL_OP_LIGHT_CTL_SET:
  780. case BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK: {
  781. struct bt_mesh_light_ctl_set *set;
  782. set = (struct bt_mesh_light_ctl_set *)value;
  783. net_buf_simple_add_le16(msg, set->ctl_lightness);
  784. net_buf_simple_add_le16(msg, set->ctl_temperature);
  785. net_buf_simple_add_le16(msg, set->ctl_delta_uv);
  786. net_buf_simple_add_u8(msg, set->tid);
  787. if (set->op_en) {
  788. net_buf_simple_add_u8(msg, set->trans_time);
  789. net_buf_simple_add_u8(msg, set->delay);
  790. }
  791. break;
  792. }
  793. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET:
  794. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK: {
  795. struct bt_mesh_light_ctl_temperature_set *set;
  796. set = (struct bt_mesh_light_ctl_temperature_set *)value;
  797. net_buf_simple_add_le16(msg, set->ctl_temperature);
  798. net_buf_simple_add_le16(msg, set->ctl_delta_uv);
  799. net_buf_simple_add_u8(msg, set->tid);
  800. if (set->op_en) {
  801. net_buf_simple_add_u8(msg, set->trans_time);
  802. net_buf_simple_add_u8(msg, set->delay);
  803. }
  804. break;
  805. }
  806. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET:
  807. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK: {
  808. struct bt_mesh_light_ctl_temperature_range_set *set;
  809. set = (struct bt_mesh_light_ctl_temperature_range_set *)value;
  810. net_buf_simple_add_le16(msg, set->range_min);
  811. net_buf_simple_add_le16(msg, set->range_max);
  812. break;
  813. }
  814. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET:
  815. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK: {
  816. struct bt_mesh_light_ctl_default_set *set;
  817. set = (struct bt_mesh_light_ctl_default_set *)value;
  818. net_buf_simple_add_le16(msg, set->lightness);
  819. net_buf_simple_add_le16(msg, set->temperature);
  820. net_buf_simple_add_le16(msg, set->delta_uv);
  821. break;
  822. }
  823. case BLE_MESH_MODEL_OP_LIGHT_HSL_SET:
  824. case BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK: {
  825. struct bt_mesh_light_hsl_set *set;
  826. set = (struct bt_mesh_light_hsl_set *)value;
  827. net_buf_simple_add_le16(msg, set->hsl_lightness);
  828. net_buf_simple_add_le16(msg, set->hsl_hue);
  829. net_buf_simple_add_le16(msg, set->hsl_saturation);
  830. net_buf_simple_add_u8(msg, set->tid);
  831. if (set->op_en) {
  832. net_buf_simple_add_u8(msg, set->trans_time);
  833. net_buf_simple_add_u8(msg, set->delay);
  834. }
  835. break;
  836. }
  837. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET:
  838. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK: {
  839. struct bt_mesh_light_hsl_hue_set *set;
  840. set = (struct bt_mesh_light_hsl_hue_set *)value;
  841. net_buf_simple_add_le16(msg, set->hue);
  842. net_buf_simple_add_u8(msg, set->tid);
  843. if (set->op_en) {
  844. net_buf_simple_add_u8(msg, set->trans_time);
  845. net_buf_simple_add_u8(msg, set->delay);
  846. }
  847. break;
  848. }
  849. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET:
  850. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK: {
  851. struct bt_mesh_light_hsl_saturation_set *set;
  852. set = (struct bt_mesh_light_hsl_saturation_set *)value;
  853. net_buf_simple_add_le16(msg, set->saturation);
  854. net_buf_simple_add_u8(msg, set->tid);
  855. if (set->op_en) {
  856. net_buf_simple_add_u8(msg, set->trans_time);
  857. net_buf_simple_add_u8(msg, set->delay);
  858. }
  859. break;
  860. }
  861. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET:
  862. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK: {
  863. struct bt_mesh_light_hsl_default_set *set;
  864. set = (struct bt_mesh_light_hsl_default_set *)value;
  865. net_buf_simple_add_le16(msg, set->lightness);
  866. net_buf_simple_add_le16(msg, set->hue);
  867. net_buf_simple_add_le16(msg, set->saturation);
  868. break;
  869. }
  870. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET:
  871. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK: {
  872. struct bt_mesh_light_hsl_range_set *set;
  873. set = (struct bt_mesh_light_hsl_range_set *)value;
  874. net_buf_simple_add_le16(msg, set->hue_range_min);
  875. net_buf_simple_add_le16(msg, set->hue_range_max);
  876. net_buf_simple_add_le16(msg, set->saturation_range_min);
  877. net_buf_simple_add_le16(msg, set->saturation_range_max);
  878. break;
  879. }
  880. case BLE_MESH_MODEL_OP_LIGHT_XYL_SET:
  881. case BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK: {
  882. struct bt_mesh_light_xyl_set *set;
  883. set = (struct bt_mesh_light_xyl_set *)value;
  884. net_buf_simple_add_le16(msg, set->xyl_lightness);
  885. net_buf_simple_add_le16(msg, set->xyl_x);
  886. net_buf_simple_add_le16(msg, set->xyl_y);
  887. net_buf_simple_add_u8(msg, set->tid);
  888. if (set->op_en) {
  889. net_buf_simple_add_u8(msg, set->trans_time);
  890. net_buf_simple_add_u8(msg, set->delay);
  891. }
  892. break;
  893. }
  894. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET:
  895. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK: {
  896. struct bt_mesh_light_xyl_default_set *set;
  897. set = (struct bt_mesh_light_xyl_default_set *)value;
  898. net_buf_simple_add_le16(msg, set->lightness);
  899. net_buf_simple_add_le16(msg, set->xyl_x);
  900. net_buf_simple_add_le16(msg, set->xyl_y);
  901. break;
  902. }
  903. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET:
  904. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK: {
  905. struct bt_mesh_light_xyl_range_set *set;
  906. set = (struct bt_mesh_light_xyl_range_set *)value;
  907. net_buf_simple_add_le16(msg, set->xyl_x_range_min);
  908. net_buf_simple_add_le16(msg, set->xyl_x_range_max);
  909. net_buf_simple_add_le16(msg, set->xyl_y_range_min);
  910. net_buf_simple_add_le16(msg, set->xyl_y_range_max);
  911. break;
  912. }
  913. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET:
  914. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK: {
  915. struct bt_mesh_light_lc_mode_set *set;
  916. set = (struct bt_mesh_light_lc_mode_set *)value;
  917. net_buf_simple_add_u8(msg, set->mode);
  918. break;
  919. }
  920. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET:
  921. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK: {
  922. struct bt_mesh_light_lc_om_set *set;
  923. set = (struct bt_mesh_light_lc_om_set *)value;
  924. net_buf_simple_add_u8(msg, set->mode);
  925. break;
  926. }
  927. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET:
  928. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK: {
  929. struct bt_mesh_light_lc_light_onoff_set *set;
  930. set = (struct bt_mesh_light_lc_light_onoff_set *)value;
  931. net_buf_simple_add_u8(msg, set->light_onoff);
  932. net_buf_simple_add_u8(msg, set->tid);
  933. if (set->op_en) {
  934. net_buf_simple_add_u8(msg, set->trans_time);
  935. net_buf_simple_add_u8(msg, set->delay);
  936. }
  937. break;
  938. }
  939. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
  940. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK: {
  941. struct bt_mesh_light_lc_property_set *set;
  942. set = (struct bt_mesh_light_lc_property_set *)value;
  943. net_buf_simple_add_le16(msg, set->light_lc_property_id);
  944. net_buf_simple_add_mem(msg, set->light_lc_property_value->data, set->light_lc_property_value->len);
  945. break;
  946. }
  947. default:
  948. BT_ERR("Invalid Lighting Set opcode 0x%04x", common->opcode);
  949. err = -EINVAL;
  950. goto end;
  951. }
  952. err = bt_mesh_client_send_msg(common, msg, need_ack, timeout_handler);
  953. end:
  954. bt_mesh_free_buf(msg);
  955. return err;
  956. }
  957. int bt_mesh_light_client_get_state(bt_mesh_client_common_param_t *common, void *get)
  958. {
  959. bt_mesh_light_client_t *client = NULL;
  960. if (!common || !common->model) {
  961. BT_ERR("%s, Invalid parameter", __func__);
  962. return -EINVAL;
  963. }
  964. client = (bt_mesh_light_client_t *)common->model->user_data;
  965. if (!client || !client->internal_data) {
  966. BT_ERR("Invalid Lighting client data");
  967. return -EINVAL;
  968. }
  969. switch (common->opcode) {
  970. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_GET:
  971. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_GET:
  972. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_GET:
  973. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_GET:
  974. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_GET:
  975. case BLE_MESH_MODEL_OP_LIGHT_CTL_GET:
  976. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_GET:
  977. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET:
  978. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_GET:
  979. case BLE_MESH_MODEL_OP_LIGHT_HSL_GET:
  980. case BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_GET:
  981. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_GET:
  982. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_GET:
  983. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_GET:
  984. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_GET:
  985. case BLE_MESH_MODEL_OP_LIGHT_XYL_GET:
  986. case BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_GET:
  987. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_GET:
  988. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_GET:
  989. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_GET:
  990. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_GET:
  991. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_GET:
  992. break;
  993. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET:
  994. if (!get) {
  995. BT_ERR("Invalid Lighting LC Property Get");
  996. return -EINVAL;
  997. }
  998. break;
  999. default:
  1000. BT_ERR("Invalid Lighting Get opcode 0x%04x", common->opcode);
  1001. return -EINVAL;
  1002. }
  1003. return light_get_state(common, get);
  1004. }
  1005. int bt_mesh_light_client_set_state(bt_mesh_client_common_param_t *common, void *set)
  1006. {
  1007. bt_mesh_light_client_t *client = NULL;
  1008. uint16_t length = 0U;
  1009. bool need_ack = false;
  1010. if (!common || !common->model || !set) {
  1011. BT_ERR("%s, Invalid parameter", __func__);
  1012. return -EINVAL;
  1013. }
  1014. client = (bt_mesh_light_client_t *)common->model->user_data;
  1015. if (!client || !client->internal_data) {
  1016. BT_ERR("Invalid Lighting client data");
  1017. return -EINVAL;
  1018. }
  1019. switch (common->opcode) {
  1020. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET:
  1021. need_ack = true;
  1022. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK: {
  1023. struct bt_mesh_light_lightness_set *value;
  1024. value = (struct bt_mesh_light_lightness_set *)set;
  1025. if (value->op_en) {
  1026. if ((value->trans_time & 0x3F) > 0x3E) {
  1027. BT_ERR("Invalid Light Lightness Set transition time");
  1028. return -EINVAL;
  1029. }
  1030. }
  1031. length = BLE_MESH_LIGHT_LIGHTNESS_SET_MSG_LEN;
  1032. break;
  1033. }
  1034. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET:
  1035. need_ack = true;
  1036. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK: {
  1037. struct bt_mesh_light_lightness_linear_set *value;
  1038. value = (struct bt_mesh_light_lightness_linear_set *)set;
  1039. if (value->op_en) {
  1040. if ((value->trans_time & 0x3F) > 0x3E) {
  1041. BT_ERR("Invalid Light Lightness Linear Set transition time");
  1042. return -EINVAL;
  1043. }
  1044. }
  1045. length = BLE_MESH_LIGHT_LIGHTNESS_LINEAR_SET_MSG_LEN;
  1046. break;
  1047. }
  1048. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET:
  1049. need_ack = true;
  1050. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK:
  1051. length = BLE_MESH_LIGHT_LIGHTNESS_DEFAULT_SET_MSG_LEN;
  1052. break;
  1053. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET:
  1054. need_ack = true;
  1055. case BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK: {
  1056. struct bt_mesh_light_lightness_range_set *value;
  1057. value = (struct bt_mesh_light_lightness_range_set *)set;
  1058. if (value->range_min > value->range_max) {
  1059. BT_ERR("Light Lightness Range Set range min is greater than range max");
  1060. return -EINVAL;
  1061. }
  1062. length = BLE_MESH_LIGHT_LIGHTNESS_RANGE_SET_MSG_LEN;
  1063. break;
  1064. }
  1065. case BLE_MESH_MODEL_OP_LIGHT_CTL_SET:
  1066. need_ack = true;
  1067. case BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK: {
  1068. struct bt_mesh_light_ctl_set *value;
  1069. value = (struct bt_mesh_light_ctl_set *)set;
  1070. if (value->op_en) {
  1071. if ((value->trans_time & 0x3F) > 0x3E) {
  1072. BT_ERR("Invalid Light CTL Set transition time");
  1073. return -EINVAL;
  1074. }
  1075. }
  1076. length = BLE_MESH_LIGHT_CTL_SET_MSG_LEN;
  1077. break;
  1078. }
  1079. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET:
  1080. need_ack = true;
  1081. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK: {
  1082. struct bt_mesh_light_ctl_temperature_set *value;
  1083. value = (struct bt_mesh_light_ctl_temperature_set *)set;
  1084. if (value->op_en) {
  1085. if ((value->trans_time & 0x3F) > 0x3E) {
  1086. BT_ERR("Invalid Light CTL Temperature Set transition time");
  1087. return -EINVAL;
  1088. }
  1089. }
  1090. length = BLE_MESH_LIGHT_CTL_TEMPERATURE_SET_MSG_LEN;
  1091. break;
  1092. }
  1093. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET:
  1094. need_ack = true;
  1095. case BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK: {
  1096. struct bt_mesh_light_ctl_temperature_range_set *value;
  1097. value = (struct bt_mesh_light_ctl_temperature_range_set *)set;
  1098. if (value->range_min > value->range_max) {
  1099. BT_ERR("Light CTL Temperature Range Set range min is greater than range max");
  1100. return -EINVAL;
  1101. }
  1102. length = BLE_MESH_LIGHT_CTL_TEMPERATURE_RANGE_SET_MSG_LEN;
  1103. break;
  1104. }
  1105. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET:
  1106. need_ack = true;
  1107. case BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK:
  1108. length = BLE_MESH_LIGHT_CTL_DEFAULT_SET_MSG_LEN;
  1109. break;
  1110. case BLE_MESH_MODEL_OP_LIGHT_HSL_SET:
  1111. need_ack = true;
  1112. case BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK: {
  1113. struct bt_mesh_light_hsl_set *value;
  1114. value = (struct bt_mesh_light_hsl_set *)set;
  1115. if (value->op_en) {
  1116. if ((value->trans_time & 0x3F) > 0x3E) {
  1117. BT_ERR("Invalid Light HSL Set transition time");
  1118. return -EINVAL;
  1119. }
  1120. }
  1121. length = BLE_MESH_LIGHT_HSL_SET_MSG_LEN;
  1122. break;
  1123. }
  1124. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET:
  1125. need_ack = true;
  1126. case BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK: {
  1127. struct bt_mesh_light_hsl_hue_set *value;
  1128. value = (struct bt_mesh_light_hsl_hue_set *)set;
  1129. if (value->op_en) {
  1130. if ((value->trans_time & 0x3F) > 0x3E) {
  1131. BT_ERR("Invalid Light HSL Hue Set transition time");
  1132. return -EINVAL;
  1133. }
  1134. }
  1135. length = BLE_MESH_LIGHT_HSL_HUE_SET_MSG_LEN;
  1136. break;
  1137. }
  1138. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET:
  1139. need_ack = true;
  1140. case BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK: {
  1141. struct bt_mesh_light_hsl_saturation_set *value;
  1142. value = (struct bt_mesh_light_hsl_saturation_set *)set;
  1143. if (value->op_en) {
  1144. if ((value->trans_time & 0x3F) > 0x3E) {
  1145. BT_ERR("Invalid Light HSL Saturation Set transition time");
  1146. return -EINVAL;
  1147. }
  1148. }
  1149. length = BLE_MESH_LIGHT_HSL_SATURATION_SET_MSG_LEN;
  1150. break;
  1151. }
  1152. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET:
  1153. need_ack = true;
  1154. case BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK:
  1155. length = BLE_MESH_LIGHT_HSL_DEFAULT_SET_MSG_LEN;
  1156. break;
  1157. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET:
  1158. need_ack = true;
  1159. case BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK: {
  1160. struct bt_mesh_light_hsl_range_set *value;
  1161. value = (struct bt_mesh_light_hsl_range_set *)set;
  1162. if (value->hue_range_min > value->hue_range_max ||
  1163. value->saturation_range_min > value->saturation_range_max) {
  1164. BT_ERR("Light HSL Range Set range min is greater than range max");
  1165. return -EINVAL;
  1166. }
  1167. length = BLE_MESH_LIGHT_HSL_RANGE_SET_MSG_LEN;
  1168. break;
  1169. }
  1170. case BLE_MESH_MODEL_OP_LIGHT_XYL_SET:
  1171. need_ack = true;
  1172. case BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK: {
  1173. struct bt_mesh_light_xyl_set *value;
  1174. value = (struct bt_mesh_light_xyl_set *)set;
  1175. if (value->op_en) {
  1176. if ((value->trans_time & 0x3F) > 0x3E) {
  1177. BT_ERR("Invalid Light xyL Set transition time");
  1178. return -EINVAL;
  1179. }
  1180. }
  1181. length = BLE_MESH_LIGHT_XYL_SET_MSG_LEN;
  1182. break;
  1183. }
  1184. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET:
  1185. need_ack = true;
  1186. case BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK:
  1187. length = BLE_MESH_LIGHT_XYL_DEFAULT_SET_MSG_LEN;
  1188. break;
  1189. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET:
  1190. need_ack = true;
  1191. case BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK: {
  1192. struct bt_mesh_light_xyl_range_set *value;
  1193. value = (struct bt_mesh_light_xyl_range_set *)set;
  1194. if (value->xyl_x_range_min > value->xyl_x_range_max ||
  1195. value->xyl_y_range_min > value->xyl_y_range_max) {
  1196. BT_ERR("Light xyL Range Set range min is greater than range max");
  1197. return -EINVAL;
  1198. }
  1199. length = BLE_MESH_LIGHT_XYL_RANGE_SET_MSG_LEN;
  1200. break;
  1201. }
  1202. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET:
  1203. need_ack = true;
  1204. case BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK:
  1205. length = BLE_MESH_LIGHT_LC_MODE_SET_MSG_LEN;
  1206. break;
  1207. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET:
  1208. need_ack = true;
  1209. case BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK:
  1210. length = BLE_MESH_LIGHT_LC_OM_SET_MSG_LEN;
  1211. break;
  1212. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET:
  1213. need_ack = true;
  1214. case BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK: {
  1215. struct bt_mesh_light_lc_light_onoff_set *value;
  1216. value = (struct bt_mesh_light_lc_light_onoff_set *)set;
  1217. if (value->op_en) {
  1218. if ((value->trans_time & 0x3F) > 0x3E) {
  1219. BT_ERR("Invalid Light LC Light OnOff Set transition time");
  1220. return -EINVAL;
  1221. }
  1222. }
  1223. length = BLE_MESH_LIGHT_LC_LIGHT_ONOFF_SET_MSG_LEN;
  1224. break;
  1225. }
  1226. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
  1227. need_ack = true;
  1228. case BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK: {
  1229. struct bt_mesh_light_lc_property_set *value;
  1230. value = (struct bt_mesh_light_lc_property_set *)set;
  1231. if (!value->light_lc_property_value) {
  1232. BT_ERR("Invalid Lighting Light LC Property value");
  1233. return -EINVAL;
  1234. }
  1235. length = (1 + 2 + value->light_lc_property_value->len + 4);
  1236. break;
  1237. }
  1238. default:
  1239. BT_ERR("Invalid Lighting Set opcode 0x%04x", common->opcode);
  1240. return -EINVAL;
  1241. }
  1242. return light_set_state(common, set, length, need_ack);
  1243. }
  1244. static int lighting_client_init(struct bt_mesh_model *model)
  1245. {
  1246. light_internal_data_t *internal = NULL;
  1247. bt_mesh_light_client_t *client = NULL;
  1248. if (!model) {
  1249. BT_ERR("Invalid Lighting client model");
  1250. return -EINVAL;
  1251. }
  1252. client = (bt_mesh_light_client_t *)model->user_data;
  1253. if (!client) {
  1254. BT_ERR("No Lighting client context provided");
  1255. return -EINVAL;
  1256. }
  1257. if (client->internal_data) {
  1258. BT_WARN("%s, Already", __func__);
  1259. return -EALREADY;
  1260. }
  1261. internal = bt_mesh_calloc(sizeof(light_internal_data_t));
  1262. if (!internal) {
  1263. BT_ERR("%s, Out of memory", __func__);
  1264. return -ENOMEM;
  1265. }
  1266. sys_slist_init(&internal->queue);
  1267. client->model = model;
  1268. client->op_pair_size = ARRAY_SIZE(light_op_pair);
  1269. client->op_pair = light_op_pair;
  1270. client->internal_data = internal;
  1271. bt_mesh_mutex_create(&lighting_client_lock);
  1272. return 0;
  1273. }
  1274. #if CONFIG_BLE_MESH_DEINIT
  1275. static int lighting_client_deinit(struct bt_mesh_model *model)
  1276. {
  1277. bt_mesh_light_client_t *client = NULL;
  1278. if (!model) {
  1279. BT_ERR("Invalid Lighting client model");
  1280. return -EINVAL;
  1281. }
  1282. client = (bt_mesh_light_client_t *)model->user_data;
  1283. if (!client) {
  1284. BT_ERR("No Lighting client context provided");
  1285. return -EINVAL;
  1286. }
  1287. if (client->internal_data) {
  1288. /* Remove items from the list */
  1289. bt_mesh_client_clear_list(client->internal_data);
  1290. /* Free the allocated internal data */
  1291. bt_mesh_free(client->internal_data);
  1292. client->internal_data = NULL;
  1293. }
  1294. bt_mesh_mutex_free(&lighting_client_lock);
  1295. return 0;
  1296. }
  1297. #endif /* CONFIG_BLE_MESH_DEINIT */
  1298. const struct bt_mesh_model_cb bt_mesh_lighting_client_cb = {
  1299. .init = lighting_client_init,
  1300. #if CONFIG_BLE_MESH_DEINIT
  1301. .deinit = lighting_client_deinit,
  1302. #endif /* CONFIG_BLE_MESH_DEINIT */
  1303. };
  1304. #endif /* CONFIG_BLE_MESH_LIGHTING_CLIENT */