generic_client.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  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_generic_model.h"
  9. #include "mesh/config.h"
  10. #include "mesh/model_opcode.h"
  11. #if CONFIG_BLE_MESH_GENERIC_CLIENT
  12. #include "mesh/generic_client.h"
  13. /* The followings are the macro definitions of Generic client
  14. * model message length, and a message is composed of 3 parts:
  15. * Opcode + Payload + MIC
  16. */
  17. /* Generic onoff client messages length */
  18. #define BLE_MESH_GEN_ONOFF_GET_MSG_LEN (2 + 0 + 4)
  19. #define BLE_MESH_GEN_ONOFF_SET_MSG_LEN (2 + 4 + 4)
  20. /* Generic level client messages length */
  21. #define BLE_MESH_GEN_LEVEL_GET_MSG_LEN (2 + 0 + 4)
  22. #define BLE_MESH_GEN_LEVEL_SET_MSG_LEN (2 + 5 + 4)
  23. #define BLE_MESH_GEN_DELTA_SET_MSG_LEN (2 + 7 + 4)
  24. #define BLE_MESH_GEN_MOVE_SET_MSG_LEN (2 + 5 + 4)
  25. /* Generic default transition time client messages length */
  26. #define BLE_MESH_GEN_DEF_TRANS_TIME_GET_MSG_LEN (2 + 0 + 4)
  27. #define BLE_MESH_GEN_DEF_TRANS_TIME_SET_MSG_LEN (2 + 1 + 4)
  28. /* Generic power onoff client messages length */
  29. #define BLE_MESH_GEN_ONPOWERUP_GET_MSG_LEN (2 + 0 + 4)
  30. #define BLE_MESH_GEN_ONPOWERUP_SET_MSG_LEN (2 + 1 + 4)
  31. /* Generic power level client messages length */
  32. #define BLE_MESH_GEN_POWER_LEVEL_GET_MSG_LEN (2 + 0 + 4)
  33. #define BLE_MESH_GEN_POWER_LEVEL_SET_MSG_LEN (2 + 5 + 4)
  34. #define BLE_MESH_GEN_POWER_LAST_GET_MSG_LEN (2 + 0 + 4)
  35. #define BLE_MESH_GEN_POWER_DEFAULT_GET_MSG_LEN (2 + 0 + 4)
  36. #define BLE_MESH_GEN_POWER_DEFAULT_SET_MSG_LEN (2 + 2 + 4)
  37. #define BLE_MESH_GEN_POWER_RANGE_GET_MSG_LEN (2 + 0 + 4)
  38. #define BLE_MESH_GEN_POWER_RANGE_SET_MSG_LEN (2 + 4 + 4)
  39. /* Generic battery client messages length */
  40. #define BLE_MESH_GEN_BATTERY_GET_MSG_LEN (2 + 0 + 4)
  41. /* Generic location client messages length */
  42. #define BLE_MESH_GEN_LOC_GLOBAL_GET_MSG_LEN (2 + 0 + 4)
  43. #define BLE_MESH_GEN_LOC_GLOBAL_SET_MSG_LEN (1 + 10 + 4)
  44. #define BLE_MESH_GEN_LOC_LOCAL_GET_MSG_LEN (2 + 0 + 4)
  45. #define BLE_MESH_GEN_LOC_LOCAL_SET_MSG_LEN (2 + 9 + 4)
  46. /* Generic property client messages length */
  47. #define BLE_MESH_GEN_USER_PROPERTIES_GET_MSG_LEN (2 + 0 + 4)
  48. #define BLE_MESH_GEN_USER_PROPERTY_GET_MSG_LEN (2 + 2 + 4)
  49. #define BLE_MESH_GEN_USER_PROPERTY_SET_MSG_LEN /* variable */
  50. #define BLE_MESH_GEN_ADMIN_PROPERTIES_GET_MSG_LEN (2 + 0 + 4)
  51. #define BLE_MESH_GEN_ADMIN_PROPERTY_GET_MSG_LEN (2 + 2 + 4)
  52. #define BLE_MESH_GEN_ADMIN_PROPERTY_SET_MSG_LEN /* variable */
  53. #define BLE_MESH_GEN_MANU_PROPERTIES_GET_MSG_LEN (2 + 0 + 4)
  54. #define BLE_MESH_GEN_MANU_PROPERTY_GET_MSG_LEN (2 + 2 + 4)
  55. #define BLE_MESH_GEN_MANU_PROPERTY_SET_MSG_LEN (1 + 3 + 4)
  56. #define BLE_MESH_GEN_CLIENT_PROPERTIES_GET_MSG_LEN (1 + 2 + 4)
  57. #define BLE_MESH_GEN_GET_STATE_MSG_LEN (2 + 2 + 4)
  58. static const bt_mesh_client_op_pair_t gen_op_pair[] = {
  59. { BLE_MESH_MODEL_OP_GEN_ONOFF_GET, BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS },
  60. { BLE_MESH_MODEL_OP_GEN_ONOFF_SET, BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS },
  61. { BLE_MESH_MODEL_OP_GEN_LEVEL_GET, BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS },
  62. { BLE_MESH_MODEL_OP_GEN_LEVEL_SET, BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS },
  63. { BLE_MESH_MODEL_OP_GEN_DELTA_SET, BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS },
  64. { BLE_MESH_MODEL_OP_GEN_MOVE_SET, BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS },
  65. { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET, BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS },
  66. { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET, BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS },
  67. { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET, BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS },
  68. { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET, BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS },
  69. { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS },
  70. { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS },
  71. { BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET, BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS },
  72. { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET, BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS },
  73. { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET, BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS },
  74. { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET, BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS },
  75. { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET, BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS },
  76. { BLE_MESH_MODEL_OP_GEN_BATTERY_GET, BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS },
  77. { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET, BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS },
  78. { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET, BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS },
  79. { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET, BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS },
  80. { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET, BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS },
  81. { BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET, BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS },
  82. { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET, BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS },
  83. { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET, BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS },
  84. { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET, BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS },
  85. { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET, BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS },
  86. { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET, BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS },
  87. { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET, BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS },
  88. { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET, BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS },
  89. { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET, BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS },
  90. { BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET, BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS },
  91. };
  92. static bt_mesh_mutex_t generic_client_lock;
  93. static void timeout_handler(struct k_work *work)
  94. {
  95. struct k_delayed_work *timer = NULL;
  96. bt_mesh_client_node_t *node = NULL;
  97. struct bt_mesh_model *model = NULL;
  98. struct bt_mesh_msg_ctx ctx = {0};
  99. uint32_t opcode = 0U;
  100. BT_WARN("Receive generic status message timeout");
  101. bt_mesh_mutex_lock(&generic_client_lock);
  102. timer = CONTAINER_OF(work, struct k_delayed_work, work);
  103. if (timer && !k_delayed_work_free(timer)) {
  104. node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
  105. if (node) {
  106. memcpy(&ctx, &node->ctx, sizeof(ctx));
  107. opcode = node->opcode;
  108. model = node->model;
  109. bt_mesh_client_free_node(node);
  110. bt_mesh_generic_client_cb_evt_to_btc(
  111. opcode, BTC_BLE_MESH_EVT_GENERIC_CLIENT_TIMEOUT, model, &ctx, NULL, 0);
  112. }
  113. }
  114. bt_mesh_mutex_unlock(&generic_client_lock);
  115. }
  116. static void generic_status(struct bt_mesh_model *model,
  117. struct bt_mesh_msg_ctx *ctx,
  118. struct net_buf_simple *buf)
  119. {
  120. bt_mesh_client_node_t *node = NULL;
  121. uint8_t *val = NULL;
  122. uint8_t evt = 0xFF;
  123. size_t len = 0U;
  124. BT_DBG("len %d, bytes %s", buf->len, bt_hex(buf->data, buf->len));
  125. switch (ctx->recv_op) {
  126. case BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS: {
  127. struct bt_mesh_gen_onoff_status *status = NULL;
  128. if (buf->len != 1 && buf->len != 3) {
  129. BT_ERR("Invalid Generic OnOff Status length %d", buf->len);
  130. return;
  131. }
  132. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_onoff_status));
  133. if (!status) {
  134. BT_ERR("%s, Out of memory", __func__);
  135. return;
  136. }
  137. status->present_onoff = net_buf_simple_pull_u8(buf);
  138. if (buf->len) {
  139. status->op_en = true;
  140. status->target_onoff = net_buf_simple_pull_u8(buf);
  141. status->remain_time = net_buf_simple_pull_u8(buf);
  142. }
  143. val = (uint8_t *)status;
  144. len = sizeof(struct bt_mesh_gen_onoff_status);
  145. break;
  146. }
  147. case BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS: {
  148. struct bt_mesh_gen_level_status *status = NULL;
  149. if (buf->len != 2 && buf->len != 5) {
  150. BT_ERR("Invalid Generic Level Status length %d", buf->len);
  151. return;
  152. }
  153. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_level_status));
  154. if (!status) {
  155. BT_ERR("%s, Out of memory", __func__);
  156. return;
  157. }
  158. status->present_level = net_buf_simple_pull_le16(buf);
  159. if (buf->len) {
  160. status->op_en = true;
  161. status->target_level = net_buf_simple_pull_le16(buf);
  162. status->remain_time = net_buf_simple_pull_u8(buf);
  163. }
  164. val = (uint8_t *)status;
  165. len = sizeof(struct bt_mesh_gen_level_status);
  166. break;
  167. }
  168. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS: {
  169. struct bt_mesh_gen_def_trans_time_status *status = NULL;
  170. if (buf->len != 1) {
  171. BT_ERR("Invalid Generic Default Trans Time Status length %d", buf->len);
  172. return;
  173. }
  174. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_def_trans_time_status));
  175. if (!status) {
  176. BT_ERR("%s, Out of memory", __func__);
  177. return;
  178. }
  179. status->trans_time = net_buf_simple_pull_u8(buf);
  180. val = (uint8_t *)status;
  181. len = sizeof(struct bt_mesh_gen_def_trans_time_status);
  182. break;
  183. }
  184. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS: {
  185. struct bt_mesh_gen_onpowerup_status *status = NULL;
  186. if (buf->len != 1) {
  187. BT_ERR("Invalid Generic OnPowerUp Status length %d", buf->len);
  188. return;
  189. }
  190. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_onpowerup_status));
  191. if (!status) {
  192. BT_ERR("%s, Out of memory", __func__);
  193. return;
  194. }
  195. status->onpowerup = net_buf_simple_pull_u8(buf);
  196. val = (uint8_t *)status;
  197. len = sizeof(struct bt_mesh_gen_onpowerup_status);
  198. break;
  199. }
  200. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS: {
  201. struct bt_mesh_gen_power_level_status *status = NULL;
  202. if (buf->len != 2 && buf->len != 5) {
  203. BT_ERR("Invalid Generic Power Level Status length %d", buf->len);
  204. return;
  205. }
  206. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_level_status));
  207. if (!status) {
  208. BT_ERR("%s, Out of memory", __func__);
  209. return;
  210. }
  211. status->present_power = net_buf_simple_pull_le16(buf);
  212. if (buf->len) {
  213. status->op_en = true;
  214. status->target_power = net_buf_simple_pull_le16(buf);
  215. status->remain_time = net_buf_simple_pull_u8(buf);
  216. }
  217. val = (uint8_t *)status;
  218. len = sizeof(struct bt_mesh_gen_power_level_status);
  219. break;
  220. }
  221. case BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS: {
  222. struct bt_mesh_gen_power_last_status *status = NULL;
  223. if (buf->len != 2) {
  224. BT_ERR("Invalid Generic Power Last Status length %d", buf->len);
  225. return;
  226. }
  227. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_last_status));
  228. if (!status) {
  229. BT_ERR("%s, Out of memory", __func__);
  230. return;
  231. }
  232. status->power = net_buf_simple_pull_le16(buf);
  233. val = (uint8_t *)status;
  234. len = sizeof(struct bt_mesh_gen_power_last_status);
  235. break;
  236. }
  237. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS: {
  238. struct bt_mesh_gen_power_default_status *status = NULL;
  239. if (buf->len != 2) {
  240. BT_ERR("Invalid Generic Power Default Status length %d", buf->len);
  241. return;
  242. }
  243. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_default_status));
  244. if (!status) {
  245. BT_ERR("%s, Out of memory", __func__);
  246. return;
  247. }
  248. status->power = net_buf_simple_pull_le16(buf);
  249. val = (uint8_t *)status;
  250. len = sizeof(struct bt_mesh_gen_power_default_status);
  251. break;
  252. }
  253. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS: {
  254. struct bt_mesh_gen_power_range_status *status = NULL;
  255. if (buf->len != 5) {
  256. BT_ERR("Invalid Generic Power Range Status length %d", buf->len);
  257. return;
  258. }
  259. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_power_range_status));
  260. if (!status) {
  261. BT_ERR("%s, Out of memory", __func__);
  262. return;
  263. }
  264. status->status_code = net_buf_simple_pull_u8(buf);
  265. status->range_min = net_buf_simple_pull_le16(buf);
  266. status->range_max = net_buf_simple_pull_le16(buf);
  267. val = (uint8_t *)status;
  268. len = sizeof(struct bt_mesh_gen_power_range_status);
  269. break;
  270. }
  271. case BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS: {
  272. struct bt_mesh_gen_battery_status *status = NULL;
  273. if (buf->len != 8) {
  274. BT_ERR("Invalid Generic Battery Status length %d", buf->len);
  275. return;
  276. }
  277. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_battery_status));
  278. if (!status) {
  279. BT_ERR("%s, Out of memory", __func__);
  280. return;
  281. }
  282. uint32_t value = 0;
  283. value = net_buf_simple_pull_le32(buf);
  284. status->battery_level = (uint8_t)value;
  285. status->time_to_discharge = (value >> 8);
  286. value = net_buf_simple_pull_le32(buf);
  287. status->time_to_charge = (value & 0xffffff);
  288. status->flags = (uint8_t)(value >> 24);
  289. val = (uint8_t *)status;
  290. len = sizeof(struct bt_mesh_gen_battery_status);
  291. break;
  292. }
  293. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS: {
  294. struct bt_mesh_gen_loc_global_status *status = NULL;
  295. if (buf->len != 10) {
  296. BT_ERR("Invalid Generic Location Global Status length %d", buf->len);
  297. return;
  298. }
  299. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_loc_global_status));
  300. if (!status) {
  301. BT_ERR("%s, Out of memory", __func__);
  302. return;
  303. }
  304. status->global_latitude = net_buf_simple_pull_le32(buf);
  305. status->global_longitude = net_buf_simple_pull_le32(buf);
  306. status->global_altitude = net_buf_simple_pull_le16(buf);
  307. val = (uint8_t *)status;
  308. len = sizeof(struct bt_mesh_gen_loc_global_status);
  309. break;
  310. }
  311. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS: {
  312. struct bt_mesh_gen_loc_local_status *status = NULL;
  313. if (buf->len != 9) {
  314. BT_ERR("Invalid Generic Location Local Status length %d", buf->len);
  315. return;
  316. }
  317. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_loc_local_status));
  318. if (!status) {
  319. BT_ERR("%s, Out of memory", __func__);
  320. return;
  321. }
  322. status->local_north = net_buf_simple_pull_le16(buf);
  323. status->local_east = net_buf_simple_pull_le16(buf);
  324. status->local_altitude = net_buf_simple_pull_le16(buf);
  325. status->floor_number = net_buf_simple_pull_u8(buf);
  326. status->uncertainty = net_buf_simple_pull_le16(buf);
  327. val = (uint8_t *)status;
  328. len = sizeof(struct bt_mesh_gen_loc_local_status);
  329. break;
  330. }
  331. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS: {
  332. struct bt_mesh_gen_user_properties_status *status = NULL;
  333. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_user_properties_status));
  334. if (!status) {
  335. BT_ERR("%s, Out of memory", __func__);
  336. return;
  337. }
  338. status->user_property_ids = bt_mesh_alloc_buf(buf->len);
  339. if (!status->user_property_ids) {
  340. BT_ERR("%s, Out of memory", __func__);
  341. bt_mesh_free(status);
  342. return;
  343. }
  344. net_buf_simple_add_mem(status->user_property_ids, buf->data, buf->len);
  345. val = (uint8_t *)status;
  346. len = sizeof(struct bt_mesh_gen_user_properties_status);
  347. break;
  348. }
  349. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS: {
  350. struct bt_mesh_gen_user_property_status *status = NULL;
  351. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_user_property_status));
  352. if (!status) {
  353. BT_ERR("%s, Out of memory", __func__);
  354. return;
  355. }
  356. status->user_property_id = net_buf_simple_pull_le16(buf);
  357. if (buf->len) {
  358. status->op_en = true;
  359. status->user_access = net_buf_simple_pull_u8(buf);
  360. status->user_property_value = bt_mesh_alloc_buf(buf->len);
  361. if (!status->user_property_value) {
  362. BT_ERR("%s, Out of memory", __func__);
  363. bt_mesh_free(status);
  364. return;
  365. }
  366. net_buf_simple_add_mem(status->user_property_value, buf->data, buf->len);
  367. }
  368. val = (uint8_t *)status;
  369. len = sizeof(struct bt_mesh_gen_user_property_status);
  370. break;
  371. }
  372. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS: {
  373. struct bt_mesh_gen_admin_properties_status *status = NULL;
  374. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_admin_properties_status));
  375. if (!status) {
  376. BT_ERR("%s, Out of memory", __func__);
  377. return;
  378. }
  379. status->admin_property_ids = bt_mesh_alloc_buf(buf->len);
  380. if (!status->admin_property_ids) {
  381. BT_ERR("%s, Out of memory", __func__);
  382. bt_mesh_free(status);
  383. return;
  384. }
  385. net_buf_simple_add_mem(status->admin_property_ids, buf->data, buf->len);
  386. val = (uint8_t *)status;
  387. len = sizeof(struct bt_mesh_gen_admin_properties_status);
  388. break;
  389. }
  390. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS: {
  391. struct bt_mesh_gen_admin_property_status *status = NULL;
  392. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_admin_property_status));
  393. if (!status) {
  394. BT_ERR("%s, Out of memory", __func__);
  395. return;
  396. }
  397. status->admin_property_id = net_buf_simple_pull_le16(buf);
  398. if (buf->len) {
  399. status->op_en = true;
  400. status->admin_user_access = net_buf_simple_pull_u8(buf);
  401. status->admin_property_value = bt_mesh_alloc_buf(buf->len);
  402. if (!status->admin_property_value) {
  403. BT_ERR("%s, Out of memory", __func__);
  404. bt_mesh_free(status);
  405. return;
  406. }
  407. net_buf_simple_add_mem(status->admin_property_value, buf->data, buf->len);
  408. }
  409. val = (uint8_t *)status;
  410. len = sizeof(struct bt_mesh_gen_admin_property_status);
  411. break;
  412. }
  413. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS: {
  414. struct bt_mesh_gen_manu_properties_status *status = NULL;
  415. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_manu_properties_status));
  416. if (!status) {
  417. BT_ERR("%s, Out of memory", __func__);
  418. return;
  419. }
  420. status->manu_property_ids = bt_mesh_alloc_buf(buf->len);
  421. if (!status->manu_property_ids) {
  422. BT_ERR("%s, Out of memory", __func__);
  423. bt_mesh_free(status);
  424. return;
  425. }
  426. net_buf_simple_add_mem(status->manu_property_ids, buf->data, buf->len);
  427. val = (uint8_t *)status;
  428. len = sizeof(struct bt_mesh_gen_manu_properties_status);
  429. break;
  430. }
  431. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS: {
  432. struct bt_mesh_gen_manu_property_status *status = NULL;
  433. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_manu_property_status));
  434. if (!status) {
  435. BT_ERR("%s, Out of memory", __func__);
  436. return;
  437. }
  438. status->manu_property_id = net_buf_simple_pull_le16(buf);
  439. if (buf->len) {
  440. status->op_en = true;
  441. status->manu_user_access = net_buf_simple_pull_u8(buf);
  442. status->manu_property_value = bt_mesh_alloc_buf(buf->len);
  443. if (!status->manu_property_value) {
  444. BT_ERR("%s, Out of memory", __func__);
  445. bt_mesh_free(status);
  446. return;
  447. }
  448. net_buf_simple_add_mem(status->manu_property_value, buf->data, buf->len);
  449. }
  450. val = (uint8_t *)status;
  451. len = sizeof(struct bt_mesh_gen_manu_property_status);
  452. break;
  453. }
  454. case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS: {
  455. struct bt_mesh_gen_client_properties_status *status = NULL;
  456. status = bt_mesh_calloc(sizeof(struct bt_mesh_gen_client_properties_status));
  457. if (!status) {
  458. BT_ERR("%s, Out of memory", __func__);
  459. return;
  460. }
  461. status->client_property_ids = bt_mesh_alloc_buf(buf->len);
  462. if (!status->client_property_ids) {
  463. BT_ERR("%s, Out of memory", __func__);
  464. bt_mesh_free(status);
  465. return;
  466. }
  467. net_buf_simple_add_mem(status->client_property_ids, buf->data, buf->len);
  468. val = (uint8_t *)status;
  469. len = sizeof(struct bt_mesh_gen_client_properties_status);
  470. break;
  471. }
  472. default:
  473. BT_ERR("Invalid Generic Status opcode 0x%04x", ctx->recv_op);
  474. return;
  475. }
  476. buf->data = val;
  477. buf->len = len;
  478. bt_mesh_mutex_lock(&generic_client_lock);
  479. node = bt_mesh_is_client_recv_publish_msg(model, ctx, buf, true);
  480. if (!node) {
  481. BT_DBG("Unexpected Generic Status 0x%04x", ctx->recv_op);
  482. } else {
  483. switch (node->opcode) {
  484. case BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
  485. case BLE_MESH_MODEL_OP_GEN_LEVEL_GET:
  486. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET:
  487. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET:
  488. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET:
  489. case BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET:
  490. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET:
  491. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET:
  492. case BLE_MESH_MODEL_OP_GEN_BATTERY_GET:
  493. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET:
  494. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET:
  495. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
  496. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
  497. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
  498. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
  499. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET:
  500. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET:
  501. case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
  502. evt = BTC_BLE_MESH_EVT_GENERIC_CLIENT_GET_STATE;
  503. break;
  504. case BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
  505. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
  506. case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
  507. case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
  508. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET:
  509. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET:
  510. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET:
  511. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET:
  512. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET:
  513. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET:
  514. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET:
  515. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
  516. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
  517. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET:
  518. evt = BTC_BLE_MESH_EVT_GENERIC_CLIENT_SET_STATE;
  519. break;
  520. default:
  521. break;
  522. }
  523. if (!k_delayed_work_free(&node->timer)) {
  524. uint32_t opcode = node->opcode;
  525. bt_mesh_client_free_node(node);
  526. bt_mesh_generic_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len);
  527. }
  528. }
  529. bt_mesh_mutex_unlock(&generic_client_lock);
  530. switch (ctx->recv_op) {
  531. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS: {
  532. struct bt_mesh_gen_user_properties_status *status;
  533. status = (struct bt_mesh_gen_user_properties_status *)val;
  534. bt_mesh_free_buf(status->user_property_ids);
  535. break;
  536. }
  537. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS: {
  538. struct bt_mesh_gen_user_property_status *status;
  539. status = (struct bt_mesh_gen_user_property_status *)val;
  540. bt_mesh_free_buf(status->user_property_value);
  541. break;
  542. }
  543. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS: {
  544. struct bt_mesh_gen_admin_properties_status *status;
  545. status = (struct bt_mesh_gen_admin_properties_status *)val;
  546. bt_mesh_free_buf(status->admin_property_ids);
  547. break;
  548. }
  549. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS: {
  550. struct bt_mesh_gen_admin_property_status *status;
  551. status = (struct bt_mesh_gen_admin_property_status *)val;
  552. bt_mesh_free_buf(status->admin_property_value);
  553. break;
  554. }
  555. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS: {
  556. struct bt_mesh_gen_manu_properties_status *status;
  557. status = (struct bt_mesh_gen_manu_properties_status *)val;
  558. bt_mesh_free_buf(status->manu_property_ids);
  559. break;
  560. }
  561. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS: {
  562. struct bt_mesh_gen_manu_property_status *status;
  563. status = (struct bt_mesh_gen_manu_property_status *)val;
  564. bt_mesh_free_buf(status->manu_property_value);
  565. break;
  566. }
  567. case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS: {
  568. struct bt_mesh_gen_client_properties_status *status;
  569. status = (struct bt_mesh_gen_client_properties_status *)val;
  570. bt_mesh_free_buf(status->client_property_ids);
  571. break;
  572. }
  573. default:
  574. break;
  575. }
  576. bt_mesh_free(val);
  577. }
  578. const struct bt_mesh_model_op bt_mesh_gen_onoff_cli_op[] = {
  579. { BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, 1, generic_status },
  580. BLE_MESH_MODEL_OP_END,
  581. };
  582. const struct bt_mesh_model_op bt_mesh_gen_level_cli_op[] = {
  583. { BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS, 2, generic_status },
  584. BLE_MESH_MODEL_OP_END,
  585. };
  586. const struct bt_mesh_model_op bt_mesh_gen_def_trans_time_cli_op[] = {
  587. { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS, 1, generic_status },
  588. BLE_MESH_MODEL_OP_END,
  589. };
  590. const struct bt_mesh_model_op bt_mesh_gen_power_onoff_cli_op[] = {
  591. { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS, 1, generic_status },
  592. BLE_MESH_MODEL_OP_END,
  593. };
  594. const struct bt_mesh_model_op bt_mesh_gen_power_level_cli_op[] = {
  595. { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS, 2, generic_status },
  596. { BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS, 2, generic_status },
  597. { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS, 2, generic_status },
  598. { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS, 5, generic_status },
  599. BLE_MESH_MODEL_OP_END,
  600. };
  601. const struct bt_mesh_model_op bt_mesh_gen_battery_cli_op[] = {
  602. { BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS, 8, generic_status },
  603. BLE_MESH_MODEL_OP_END,
  604. };
  605. const struct bt_mesh_model_op bt_mesh_gen_location_cli_op[] = {
  606. { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS, 10, generic_status },
  607. { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS, 9, generic_status },
  608. BLE_MESH_MODEL_OP_END,
  609. };
  610. const struct bt_mesh_model_op bt_mesh_gen_property_cli_op[] = {
  611. { BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS, 2, generic_status },
  612. { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS, 2, generic_status },
  613. { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS, 2, generic_status },
  614. { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS, 2, generic_status },
  615. { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS, 2, generic_status },
  616. { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS, 2, generic_status },
  617. { BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS, 2, generic_status },
  618. BLE_MESH_MODEL_OP_END,
  619. };
  620. static int gen_get_state(bt_mesh_client_common_param_t *common, void *value)
  621. {
  622. NET_BUF_SIMPLE_DEFINE(msg, BLE_MESH_GEN_GET_STATE_MSG_LEN);
  623. bt_mesh_model_msg_init(&msg, common->opcode);
  624. if (value) {
  625. switch (common->opcode) {
  626. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET: {
  627. struct bt_mesh_gen_user_property_get *get;
  628. get = (struct bt_mesh_gen_user_property_get *)value;
  629. net_buf_simple_add_le16(&msg, get->user_property_id);
  630. break;
  631. }
  632. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET: {
  633. struct bt_mesh_gen_admin_property_get *get;
  634. get = (struct bt_mesh_gen_admin_property_get *)value;
  635. net_buf_simple_add_le16(&msg, get->admin_property_id);
  636. break;
  637. }
  638. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET: {
  639. struct bt_mesh_gen_manu_property_get *get;
  640. get = (struct bt_mesh_gen_manu_property_get *)value;
  641. net_buf_simple_add_le16(&msg, get->manu_property_id);
  642. break;
  643. }
  644. case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET: {
  645. struct bt_mesh_gen_client_properties_get *get;
  646. get = (struct bt_mesh_gen_client_properties_get *)value;
  647. net_buf_simple_add_le16(&msg, get->client_property_id);
  648. break;
  649. }
  650. default:
  651. BT_DBG("No parameters for Generic Get 0x%04x", common->opcode);
  652. break;
  653. }
  654. }
  655. return bt_mesh_client_send_msg(common, &msg, true, timeout_handler);
  656. }
  657. static int gen_set_state(bt_mesh_client_common_param_t *common,
  658. void *value, uint16_t value_len, bool need_ack)
  659. {
  660. struct net_buf_simple *msg = NULL;
  661. int err = 0;
  662. msg = bt_mesh_alloc_buf(value_len);
  663. if (!msg) {
  664. BT_ERR("%s, Out of memory", __func__);
  665. return -ENOMEM;
  666. }
  667. bt_mesh_model_msg_init(msg, common->opcode);
  668. switch (common->opcode) {
  669. case BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
  670. case BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK: {
  671. struct bt_mesh_gen_onoff_set *set;
  672. set = (struct bt_mesh_gen_onoff_set *)value;
  673. net_buf_simple_add_u8(msg, set->onoff);
  674. net_buf_simple_add_u8(msg, set->tid);
  675. if (set->op_en) {
  676. net_buf_simple_add_u8(msg, set->trans_time);
  677. net_buf_simple_add_u8(msg, set->delay);
  678. }
  679. break;
  680. }
  681. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
  682. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK: {
  683. struct bt_mesh_gen_level_set *set;
  684. set = (struct bt_mesh_gen_level_set *)value;
  685. net_buf_simple_add_le16(msg, set->level);
  686. net_buf_simple_add_u8(msg, set->tid);
  687. if (set->op_en) {
  688. net_buf_simple_add_u8(msg, set->trans_time);
  689. net_buf_simple_add_u8(msg, set->delay);
  690. }
  691. break;
  692. }
  693. case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
  694. case BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK: {
  695. struct bt_mesh_gen_delta_set *set;
  696. set = (struct bt_mesh_gen_delta_set *)value;
  697. net_buf_simple_add_le32(msg, set->delta_level);
  698. net_buf_simple_add_u8(msg, set->tid);
  699. if (set->op_en) {
  700. net_buf_simple_add_u8(msg, set->trans_time);
  701. net_buf_simple_add_u8(msg, set->delay);
  702. }
  703. break;
  704. }
  705. case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
  706. case BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK: {
  707. struct bt_mesh_gen_move_set *set;
  708. set = (struct bt_mesh_gen_move_set *)value;
  709. net_buf_simple_add_le16(msg, set->delta_level);
  710. net_buf_simple_add_u8(msg, set->tid);
  711. if (set->op_en) {
  712. net_buf_simple_add_u8(msg, set->trans_time);
  713. net_buf_simple_add_u8(msg, set->delay);
  714. }
  715. break;
  716. }
  717. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET:
  718. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK: {
  719. struct bt_mesh_gen_def_trans_time_set *set;
  720. set = (struct bt_mesh_gen_def_trans_time_set *)value;
  721. net_buf_simple_add_u8(msg, set->trans_time);
  722. break;
  723. }
  724. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET:
  725. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK: {
  726. struct bt_mesh_gen_onpowerup_set *set;
  727. set = (struct bt_mesh_gen_onpowerup_set *)value;
  728. net_buf_simple_add_u8(msg, set->onpowerup);
  729. break;
  730. }
  731. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET:
  732. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK: {
  733. struct bt_mesh_gen_power_level_set *set;
  734. set = (struct bt_mesh_gen_power_level_set *)value;
  735. net_buf_simple_add_le16(msg, set->power);
  736. net_buf_simple_add_u8(msg, set->tid);
  737. if (set->op_en) {
  738. net_buf_simple_add_u8(msg, set->trans_time);
  739. net_buf_simple_add_u8(msg, set->delay);
  740. }
  741. break;
  742. }
  743. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET:
  744. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK: {
  745. struct bt_mesh_gen_power_default_set *set;
  746. set = (struct bt_mesh_gen_power_default_set *)value;
  747. net_buf_simple_add_le16(msg, set->power);
  748. break;
  749. }
  750. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET:
  751. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK: {
  752. struct bt_mesh_gen_power_range_set *set;
  753. set = (struct bt_mesh_gen_power_range_set *)value;
  754. net_buf_simple_add_le16(msg, set->range_min);
  755. net_buf_simple_add_le16(msg, set->range_max);
  756. break;
  757. }
  758. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET:
  759. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK: {
  760. struct bt_mesh_gen_loc_global_set *set;
  761. set = (struct bt_mesh_gen_loc_global_set *)value;
  762. net_buf_simple_add_le32(msg, set->global_latitude);
  763. net_buf_simple_add_le32(msg, set->global_longitude);
  764. net_buf_simple_add_le16(msg, set->global_altitude);
  765. break;
  766. }
  767. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET:
  768. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK: {
  769. struct bt_mesh_gen_loc_local_set *set;
  770. set = (struct bt_mesh_gen_loc_local_set *)value;
  771. net_buf_simple_add_le16(msg, set->local_north);
  772. net_buf_simple_add_le16(msg, set->local_east);
  773. net_buf_simple_add_le16(msg, set->local_altitude);
  774. net_buf_simple_add_u8(msg, set->floor_number);
  775. net_buf_simple_add_le16(msg, set->uncertainty);
  776. break;
  777. }
  778. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
  779. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK: {
  780. struct bt_mesh_gen_user_property_set *set;
  781. set = (struct bt_mesh_gen_user_property_set *)value;
  782. net_buf_simple_add_le16(msg, set->user_property_id);
  783. net_buf_simple_add_mem(msg, set->user_property_value->data, set->user_property_value->len);
  784. break;
  785. }
  786. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
  787. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK: {
  788. struct bt_mesh_gen_admin_property_set *set;
  789. set = (struct bt_mesh_gen_admin_property_set *)value;
  790. net_buf_simple_add_le16(msg, set->admin_property_id);
  791. net_buf_simple_add_u8(msg, set->admin_user_access);
  792. net_buf_simple_add_mem(msg, set->admin_property_value->data, set->admin_property_value->len);
  793. break;
  794. }
  795. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET:
  796. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET_UNACK: {
  797. struct bt_mesh_gen_manu_property_set *set;
  798. set = (struct bt_mesh_gen_manu_property_set *)value;
  799. net_buf_simple_add_le16(msg, set->manu_property_id);
  800. net_buf_simple_add_u8(msg, set->manu_user_access);
  801. break;
  802. }
  803. default:
  804. BT_ERR("Invalid Generic Set opcode 0x%04x", common->opcode);
  805. err = -EINVAL;
  806. goto end;
  807. }
  808. err = bt_mesh_client_send_msg(common, msg, need_ack, timeout_handler);
  809. end:
  810. bt_mesh_free_buf(msg);
  811. return err;
  812. }
  813. int bt_mesh_generic_client_get_state(bt_mesh_client_common_param_t *common, void *get)
  814. {
  815. bt_mesh_generic_client_t *client = NULL;
  816. if (!common || !common->model) {
  817. BT_ERR("%s, Invalid parameter", __func__);
  818. return -EINVAL;
  819. }
  820. client = (bt_mesh_generic_client_t *)common->model->user_data;
  821. if (!client || !client->internal_data) {
  822. BT_ERR("Invalid Generic client data");
  823. return -EINVAL;
  824. }
  825. switch (common->opcode) {
  826. case BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
  827. case BLE_MESH_MODEL_OP_GEN_LEVEL_GET:
  828. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET:
  829. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET:
  830. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET:
  831. case BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET:
  832. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET:
  833. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET:
  834. case BLE_MESH_MODEL_OP_GEN_BATTERY_GET:
  835. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET:
  836. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET:
  837. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
  838. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
  839. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET:
  840. break;
  841. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
  842. if (!get) {
  843. BT_ERR("Invalid Generic User Property Get");
  844. return -EINVAL;
  845. }
  846. break;
  847. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
  848. if (!get) {
  849. BT_ERR("Invalid Generic Admin Property Get");
  850. return -EINVAL;
  851. }
  852. break;
  853. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET:
  854. if (!get) {
  855. BT_ERR("Invalid Generic Manu Property Get");
  856. return -EINVAL;
  857. }
  858. break;
  859. case BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
  860. if (!get) {
  861. BT_ERR("Invalid Generic Client Properties Get");
  862. return -EINVAL;
  863. }
  864. break;
  865. default:
  866. BT_ERR("Invalid Generic Get opcode 0x%04x", common->opcode);
  867. return -EINVAL;
  868. }
  869. return gen_get_state(common, get);
  870. }
  871. int bt_mesh_generic_client_set_state(bt_mesh_client_common_param_t *common, void *set)
  872. {
  873. bt_mesh_generic_client_t *client = NULL;
  874. uint16_t length = 0U;
  875. bool need_ack = false;
  876. if (!common || !common->model || !set) {
  877. BT_ERR("%s, Invalid parameter", __func__);
  878. return -EINVAL;
  879. }
  880. client = (bt_mesh_generic_client_t *)common->model->user_data;
  881. if (!client || !client->internal_data) {
  882. BT_ERR("Invalid Generic client data");
  883. return -EINVAL;
  884. }
  885. switch (common->opcode) {
  886. case BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
  887. need_ack = true;
  888. case BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK: {
  889. struct bt_mesh_gen_onoff_set *value;
  890. value = (struct bt_mesh_gen_onoff_set *)set;
  891. if (value->op_en) {
  892. if ((value->trans_time & 0x3F) > 0x3E) {
  893. BT_ERR("Invalid Generic OnOff Set transition time");
  894. return -EINVAL;
  895. }
  896. }
  897. length = BLE_MESH_GEN_ONOFF_SET_MSG_LEN;
  898. break;
  899. }
  900. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET:
  901. need_ack = true;
  902. case BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK: {
  903. struct bt_mesh_gen_level_set *value;
  904. value = (struct bt_mesh_gen_level_set *)set;
  905. if (value->op_en) {
  906. if ((value->trans_time & 0x3F) > 0x3E) {
  907. BT_ERR("Invalid Generic Level Set transition time");
  908. return -EINVAL;
  909. }
  910. }
  911. length = BLE_MESH_GEN_LEVEL_SET_MSG_LEN;
  912. break;
  913. }
  914. case BLE_MESH_MODEL_OP_GEN_DELTA_SET:
  915. need_ack = true;
  916. case BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK: {
  917. struct bt_mesh_gen_delta_set *value;
  918. value = (struct bt_mesh_gen_delta_set *)set;
  919. if (value->op_en) {
  920. if ((value->trans_time & 0x3F) > 0x3E) {
  921. BT_ERR("Invalid Generic Delta Set transition time");
  922. return -EINVAL;
  923. }
  924. }
  925. length = BLE_MESH_GEN_DELTA_SET_MSG_LEN;
  926. break;
  927. }
  928. case BLE_MESH_MODEL_OP_GEN_MOVE_SET:
  929. need_ack = true;
  930. case BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK: {
  931. struct bt_mesh_gen_move_set *value;
  932. value = (struct bt_mesh_gen_move_set *)set;
  933. if (value->op_en) {
  934. if ((value->trans_time & 0x3F) > 0x3E) {
  935. BT_ERR("Invalid Generic Move Set transition time");
  936. return -EINVAL;
  937. }
  938. }
  939. length = BLE_MESH_GEN_MOVE_SET_MSG_LEN;
  940. break;
  941. }
  942. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET:
  943. need_ack = true;
  944. case BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK: {
  945. uint8_t value = *(uint8_t *)set;
  946. if ((value & 0x3F) > 0x3E) {
  947. BT_ERR("Invalid Generic Default Trans Time Set transition time");
  948. return -EINVAL;
  949. }
  950. length = BLE_MESH_GEN_DEF_TRANS_TIME_SET_MSG_LEN;
  951. break;
  952. }
  953. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET:
  954. need_ack = true;
  955. case BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK:
  956. length = BLE_MESH_GEN_ONPOWERUP_SET_MSG_LEN;
  957. break;
  958. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET:
  959. need_ack = true;
  960. case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK: {
  961. struct bt_mesh_gen_power_level_set *value;
  962. value = (struct bt_mesh_gen_power_level_set *)set;
  963. if (value->op_en) {
  964. if ((value->trans_time & 0x3F) > 0x3E) {
  965. BT_ERR("Invalid Generic Power Level Set transition time");
  966. return -EINVAL;
  967. }
  968. }
  969. length = BLE_MESH_GEN_POWER_LEVEL_SET_MSG_LEN;
  970. break;
  971. }
  972. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET:
  973. need_ack = true;
  974. case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK:
  975. length = BLE_MESH_GEN_POWER_DEFAULT_SET_MSG_LEN;
  976. break;
  977. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET:
  978. need_ack = true;
  979. case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK: {
  980. struct bt_mesh_gen_power_range_set *value;
  981. value = (struct bt_mesh_gen_power_range_set *)set;
  982. if (value->range_min > value->range_max) {
  983. BT_ERR("Generic Power Level Set range min is greater than range max");
  984. return -EINVAL;
  985. }
  986. length = BLE_MESH_GEN_POWER_RANGE_SET_MSG_LEN;
  987. break;
  988. }
  989. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET:
  990. need_ack = true;
  991. case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK:
  992. length = BLE_MESH_GEN_LOC_GLOBAL_SET_MSG_LEN;
  993. break;
  994. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET:
  995. need_ack = true;
  996. case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK:
  997. length = BLE_MESH_GEN_LOC_LOCAL_SET_MSG_LEN;
  998. break;
  999. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
  1000. need_ack = true;
  1001. case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK: {
  1002. struct bt_mesh_gen_user_property_set *value;
  1003. value = (struct bt_mesh_gen_user_property_set *)set;
  1004. if (!value->user_property_value) {
  1005. BT_ERR("Invalid Generic User Property value");
  1006. return -EINVAL;
  1007. }
  1008. length = (1 + 2 + value->user_property_value->len + 4);
  1009. break;
  1010. }
  1011. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
  1012. need_ack = true;
  1013. case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK: {
  1014. struct bt_mesh_gen_admin_property_set *value;
  1015. value = (struct bt_mesh_gen_admin_property_set *)set;
  1016. if (!value->admin_property_value) {
  1017. BT_ERR("Invalid Generic Admin Property value");
  1018. return -EINVAL;
  1019. }
  1020. length = (1 + 2 + 1 + value->admin_property_value->len + 4);
  1021. break;
  1022. }
  1023. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET:
  1024. need_ack = true;
  1025. case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET_UNACK:
  1026. length = BLE_MESH_GEN_MANU_PROPERTY_SET_MSG_LEN;
  1027. break;
  1028. default:
  1029. BT_ERR("Invalid Generic Set opcode 0x%04x", common->opcode);
  1030. return -EINVAL;
  1031. }
  1032. return gen_set_state(common, set, length, need_ack);
  1033. }
  1034. static int generic_client_init(struct bt_mesh_model *model)
  1035. {
  1036. generic_internal_data_t *internal = NULL;
  1037. bt_mesh_generic_client_t *client = NULL;
  1038. if (!model) {
  1039. BT_ERR("Invalid Generic client model");
  1040. return -EINVAL;
  1041. }
  1042. client = (bt_mesh_generic_client_t *)model->user_data;
  1043. if (!client) {
  1044. BT_ERR("No Generic client context provided");
  1045. return -EINVAL;
  1046. }
  1047. if (client->internal_data) {
  1048. BT_WARN("%s, Already", __func__);
  1049. return -EALREADY;
  1050. }
  1051. internal = bt_mesh_calloc(sizeof(generic_internal_data_t));
  1052. if (!internal) {
  1053. BT_ERR("%s, Out of memory", __func__);
  1054. return -ENOMEM;
  1055. }
  1056. sys_slist_init(&internal->queue);
  1057. client->model = model;
  1058. client->op_pair_size = ARRAY_SIZE(gen_op_pair);
  1059. client->op_pair = gen_op_pair;
  1060. client->internal_data = internal;
  1061. bt_mesh_mutex_create(&generic_client_lock);
  1062. return 0;
  1063. }
  1064. #if CONFIG_BLE_MESH_DEINIT
  1065. static int generic_client_deinit(struct bt_mesh_model *model)
  1066. {
  1067. bt_mesh_generic_client_t *client = NULL;
  1068. if (!model) {
  1069. BT_ERR("Invalid Generic client model");
  1070. return -EINVAL;
  1071. }
  1072. client = (bt_mesh_generic_client_t *)model->user_data;
  1073. if (!client) {
  1074. BT_ERR("No Generic client context provided");
  1075. return -EINVAL;
  1076. }
  1077. if (client->internal_data) {
  1078. /* Remove items from the list */
  1079. bt_mesh_client_clear_list(client->internal_data);
  1080. /* Free the allocated internal data */
  1081. bt_mesh_free(client->internal_data);
  1082. client->internal_data = NULL;
  1083. }
  1084. bt_mesh_mutex_free(&generic_client_lock);
  1085. return 0;
  1086. }
  1087. #endif /* CONFIG_BLE_MESH_DEINIT */
  1088. const struct bt_mesh_model_cb bt_mesh_generic_client_cb = {
  1089. .init = generic_client_init,
  1090. #if CONFIG_BLE_MESH_DEINIT
  1091. .deinit = generic_client_deinit,
  1092. #endif /* CONFIG_BLE_MESH_DEINIT */
  1093. };
  1094. #endif /* CONFIG_BLE_MESH_GENERIC_CLIENT */