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