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 #include "esp_ble_mesh_generic_model_api.h"
12 
13 #if CONFIG_BLE_MESH_GENERIC_CLIENT
14 #include "generic_client.h"
15 
16 /* Generic Client Models related functions */
17 
btc_ble_mesh_generic_client_cb_to_app(esp_ble_mesh_generic_client_cb_event_t event,esp_ble_mesh_generic_client_cb_param_t * param)18 static inline void btc_ble_mesh_generic_client_cb_to_app(esp_ble_mesh_generic_client_cb_event_t event,
19                                                          esp_ble_mesh_generic_client_cb_param_t *param)
20 {
21     esp_ble_mesh_generic_client_cb_t btc_ble_mesh_cb =
22         (esp_ble_mesh_generic_client_cb_t)btc_profile_cb_get(BTC_PID_GENERIC_CLIENT);
23     if (btc_ble_mesh_cb) {
24         btc_ble_mesh_cb(event, param);
25     }
26 }
27 
btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t * msg,void * p_dest,void * p_src)28 void btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
29 {
30     btc_ble_mesh_generic_client_args_t *dst = (btc_ble_mesh_generic_client_args_t *)p_dest;
31     btc_ble_mesh_generic_client_args_t *src = (btc_ble_mesh_generic_client_args_t *)p_src;
32     uint16_t length = 0U;
33 
34     if (!msg || !dst || !src) {
35         BT_ERR("%s, Invalid parameter", __func__);
36         return;
37     }
38 
39     switch (msg->act) {
40     case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE: {
41         dst->generic_client_get_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t));
42         if (dst->generic_client_get_state.params) {
43             memcpy(dst->generic_client_get_state.params, src->generic_client_get_state.params,
44                    sizeof(esp_ble_mesh_client_common_param_t));
45         } else {
46             BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
47             break;
48         }
49         if (src->generic_client_get_state.get_state) {
50             dst->generic_client_get_state.get_state = (esp_ble_mesh_generic_client_get_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_generic_client_get_state_t));
51             if (dst->generic_client_get_state.get_state) {
52                 memcpy(dst->generic_client_get_state.get_state, src->generic_client_get_state.get_state,
53                     sizeof(esp_ble_mesh_generic_client_get_state_t));
54             } else {
55                 BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
56             }
57         }
58         break;
59     }
60     case BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE: {
61         dst->generic_client_set_state.params = (esp_ble_mesh_client_common_param_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t));
62         dst->generic_client_set_state.set_state = (esp_ble_mesh_generic_client_set_state_t *)bt_mesh_malloc(sizeof(esp_ble_mesh_generic_client_set_state_t));
63         if (dst->generic_client_set_state.params && dst->generic_client_set_state.set_state) {
64             memcpy(dst->generic_client_set_state.params, src->generic_client_set_state.params,
65                    sizeof(esp_ble_mesh_client_common_param_t));
66             memcpy(dst->generic_client_set_state.set_state, src->generic_client_set_state.set_state,
67                    sizeof(esp_ble_mesh_generic_client_set_state_t));
68 
69             switch (src->generic_client_set_state.params->opcode) {
70             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
71                 if (src->generic_client_set_state.set_state->user_property_set.property_value) {
72                     length = src->generic_client_set_state.set_state->user_property_set.property_value->len;
73                     dst->generic_client_set_state.set_state->user_property_set.property_value = bt_mesh_alloc_buf(length);
74                     if (!dst->generic_client_set_state.set_state->user_property_set.property_value) {
75                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
76                         return;
77                     }
78                     net_buf_simple_add_mem(dst->generic_client_set_state.set_state->user_property_set.property_value,
79                                            src->generic_client_set_state.set_state->user_property_set.property_value->data,
80                                            src->generic_client_set_state.set_state->user_property_set.property_value->len);
81                 }
82                 break;
83             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
84                 if (src->generic_client_set_state.set_state->admin_property_set.property_value) {
85                     length = src->generic_client_set_state.set_state->admin_property_set.property_value->len;
86                     dst->generic_client_set_state.set_state->admin_property_set.property_value = bt_mesh_alloc_buf(length);
87                     if (!dst->generic_client_set_state.set_state->admin_property_set.property_value) {
88                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
89                         return;
90                     }
91                     net_buf_simple_add_mem(dst->generic_client_set_state.set_state->admin_property_set.property_value,
92                                            src->generic_client_set_state.set_state->admin_property_set.property_value->data,
93                                            src->generic_client_set_state.set_state->admin_property_set.property_value->len);
94                 }
95                 break;
96             default:
97                 break;
98             }
99         } else {
100             BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
101         }
102         break;
103     }
104     default:
105         BT_DBG("%s, Unknown act %d", __func__, msg->act);
106         break;
107     }
108 }
109 
btc_ble_mesh_generic_client_arg_deep_free(btc_msg_t * msg)110 void btc_ble_mesh_generic_client_arg_deep_free(btc_msg_t *msg)
111 {
112     btc_ble_mesh_generic_client_args_t *arg = NULL;
113 
114     if (!msg) {
115         BT_ERR("%s, Invalid parameter", __func__);
116         return;
117     }
118 
119     arg = (btc_ble_mesh_generic_client_args_t *)(msg->arg);
120 
121     switch (msg->act) {
122     case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE:
123         if (arg->generic_client_get_state.params) {
124             bt_mesh_free(arg->generic_client_get_state.params);
125         }
126         if (arg->generic_client_get_state.get_state) {
127             bt_mesh_free(arg->generic_client_get_state.get_state);
128         }
129         break;
130     case BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE:
131         if (arg->generic_client_set_state.set_state) {
132             if (arg->generic_client_set_state.params) {
133                 switch (arg->generic_client_set_state.params->opcode) {
134                 case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
135                     bt_mesh_free_buf(arg->generic_client_set_state.set_state->user_property_set.property_value);
136                     break;
137                 case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
138                     bt_mesh_free_buf(arg->generic_client_set_state.set_state->admin_property_set.property_value);
139                     break;
140                 default:
141                     break;
142                 }
143             }
144             bt_mesh_free(arg->generic_client_set_state.set_state);
145         }
146         if (arg->generic_client_set_state.params) {
147             bt_mesh_free(arg->generic_client_set_state.params);
148         }
149         break;
150     default:
151         break;
152     }
153 }
154 
btc_ble_mesh_generic_client_copy_req_data(btc_msg_t * msg,void * p_dest,void * p_src)155 static void btc_ble_mesh_generic_client_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
156 {
157     esp_ble_mesh_generic_client_cb_param_t *p_dest_data = (esp_ble_mesh_generic_client_cb_param_t *)p_dest;
158     esp_ble_mesh_generic_client_cb_param_t *p_src_data = (esp_ble_mesh_generic_client_cb_param_t *)p_src;
159     uint16_t length = 0U;
160 
161     if (!msg || !p_src_data || !p_dest_data) {
162         BT_ERR("%s, Invalid parameter", __func__);
163         return;
164     }
165 
166     if (p_src_data->params) {
167         p_dest_data->params = bt_mesh_malloc(sizeof(esp_ble_mesh_client_common_param_t));
168         if (!p_dest_data->params) {
169             BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
170             return;
171         }
172 
173         memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
174     }
175 
176     switch (msg->act) {
177     case ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT:
178     case ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT:
179     case ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT:
180         if (p_src_data->params) {
181             switch (p_src_data->params->opcode) {
182             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
183             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS:
184                 if (p_src_data->status_cb.user_properties_status.property_ids) {
185                     length = p_src_data->status_cb.user_properties_status.property_ids->len;
186                     p_dest_data->status_cb.user_properties_status.property_ids = bt_mesh_alloc_buf(length);
187                     if (!p_dest_data->status_cb.user_properties_status.property_ids) {
188                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
189                         return;
190                     }
191                     net_buf_simple_add_mem(p_dest_data->status_cb.user_properties_status.property_ids,
192                                            p_src_data->status_cb.user_properties_status.property_ids->data,
193                                            p_src_data->status_cb.user_properties_status.property_ids->len);
194                 }
195                 break;
196             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
197             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
198             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS:
199                 if (p_src_data->status_cb.user_property_status.property_value) {
200                     length = p_src_data->status_cb.user_property_status.property_value->len;
201                     p_dest_data->status_cb.user_property_status.property_value = bt_mesh_alloc_buf(length);
202                     if (!p_dest_data->status_cb.user_property_status.property_value) {
203                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
204                         return;
205                     }
206                     net_buf_simple_add_mem(p_dest_data->status_cb.user_property_status.property_value,
207                                            p_src_data->status_cb.user_property_status.property_value->data,
208                                            p_src_data->status_cb.user_property_status.property_value->len);
209                 }
210                 break;
211             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
212             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS:
213                 if (p_src_data->status_cb.admin_properties_status.property_ids) {
214                     length = p_src_data->status_cb.admin_properties_status.property_ids->len;
215                     p_dest_data->status_cb.admin_properties_status.property_ids = bt_mesh_alloc_buf(length);
216                     if (!p_dest_data->status_cb.admin_properties_status.property_ids) {
217                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
218                         return;
219                     }
220                     net_buf_simple_add_mem(p_dest_data->status_cb.admin_properties_status.property_ids,
221                                            p_src_data->status_cb.admin_properties_status.property_ids->data,
222                                            p_src_data->status_cb.admin_properties_status.property_ids->len);
223                 }
224                 break;
225             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
226             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
227             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS:
228                 if (p_src_data->status_cb.admin_property_status.property_value) {
229                     length = p_src_data->status_cb.admin_property_status.property_value->len;
230                     p_dest_data->status_cb.admin_property_status.property_value = bt_mesh_alloc_buf(length);
231                     if (!p_dest_data->status_cb.admin_property_status.property_value) {
232                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
233                         return;
234                     }
235                     net_buf_simple_add_mem(p_dest_data->status_cb.admin_property_status.property_value,
236                                            p_src_data->status_cb.admin_property_status.property_value->data,
237                                            p_src_data->status_cb.admin_property_status.property_value->len);
238                 }
239                 break;
240             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_GET:
241             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_STATUS:
242                 if (p_src_data->status_cb.manufacturer_properties_status.property_ids) {
243                     length = p_src_data->status_cb.manufacturer_properties_status.property_ids->len;
244                     p_dest_data->status_cb.manufacturer_properties_status.property_ids = bt_mesh_alloc_buf(length);
245                     if (!p_dest_data->status_cb.manufacturer_properties_status.property_ids) {
246                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
247                         return;
248                     }
249                     net_buf_simple_add_mem(p_dest_data->status_cb.manufacturer_properties_status.property_ids,
250                                            p_src_data->status_cb.manufacturer_properties_status.property_ids->data,
251                                            p_src_data->status_cb.manufacturer_properties_status.property_ids->len);
252                 }
253                 break;
254             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_GET:
255             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET:
256             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS:
257                 if (p_src_data->status_cb.manufacturer_property_status.property_value) {
258                     length = p_src_data->status_cb.manufacturer_property_status.property_value->len;
259                     p_dest_data->status_cb.manufacturer_property_status.property_value = bt_mesh_alloc_buf(length);
260                     if (!p_dest_data->status_cb.manufacturer_property_status.property_value) {
261                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
262                         return;
263                     }
264                     net_buf_simple_add_mem(p_dest_data->status_cb.manufacturer_property_status.property_value,
265                                            p_src_data->status_cb.manufacturer_property_status.property_value->data,
266                                            p_src_data->status_cb.manufacturer_property_status.property_value->len);
267                 }
268                 break;
269             case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
270             case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS:
271                 if (p_src_data->status_cb.client_properties_status.property_ids) {
272                     length = p_src_data->status_cb.client_properties_status.property_ids->len;
273                     p_dest_data->status_cb.client_properties_status.property_ids = bt_mesh_alloc_buf(length);
274                     if (!p_dest_data->status_cb.client_properties_status.property_ids) {
275                         BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
276                         return;
277                     }
278                     net_buf_simple_add_mem(p_dest_data->status_cb.client_properties_status.property_ids,
279                                            p_src_data->status_cb.client_properties_status.property_ids->data,
280                                            p_src_data->status_cb.client_properties_status.property_ids->len);
281                 }
282                 break;
283             default:
284                 break;
285             }
286         }
287     case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT:
288         break;
289     default:
290         break;
291     }
292 }
293 
btc_ble_mesh_generic_client_free_req_data(btc_msg_t * msg)294 static void btc_ble_mesh_generic_client_free_req_data(btc_msg_t *msg)
295 {
296     esp_ble_mesh_generic_client_cb_param_t *arg = NULL;
297 
298     if (!msg) {
299         BT_ERR("%s, Invalid parameter", __func__);
300         return;
301     }
302 
303     arg = (esp_ble_mesh_generic_client_cb_param_t *)(msg->arg);
304 
305     switch (msg->act) {
306     case ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT:
307     case ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT:
308     case ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT:
309         if (arg->params) {
310             switch (arg->params->opcode) {
311             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
312             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS:
313                 bt_mesh_free_buf(arg->status_cb.user_properties_status.property_ids);
314                 break;
315             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
316             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
317             case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS:
318                 bt_mesh_free_buf(arg->status_cb.user_property_status.property_value);
319                 break;
320             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
321             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS:
322                 bt_mesh_free_buf(arg->status_cb.admin_properties_status.property_ids);
323                 break;
324             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
325             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
326             case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS:
327                 bt_mesh_free_buf(arg->status_cb.admin_property_status.property_value);
328                 break;
329             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_GET:
330             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_STATUS:
331                 bt_mesh_free_buf(arg->status_cb.manufacturer_properties_status.property_ids);
332                 break;
333             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_GET:
334             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET:
335             case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS:
336                 bt_mesh_free_buf(arg->status_cb.manufacturer_property_status.property_value);
337                 break;
338             case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
339             case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS:
340                 bt_mesh_free_buf(arg->status_cb.client_properties_status.property_ids);
341                 break;
342             default:
343                 break;
344             }
345         }
346     case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT:
347         if (arg->params) {
348             bt_mesh_free(arg->params);
349         }
350         break;
351     default:
352         break;
353     }
354 }
355 
btc_ble_mesh_generic_client_callback(esp_ble_mesh_generic_client_cb_param_t * cb_params,uint8_t act)356 static void btc_ble_mesh_generic_client_callback(esp_ble_mesh_generic_client_cb_param_t *cb_params, uint8_t act)
357 {
358     btc_msg_t msg = {0};
359 
360     BT_DBG("%s", __func__);
361 
362     /* If corresponding callback is not registered, event will not be posted. */
363     if (!btc_profile_cb_get(BTC_PID_GENERIC_CLIENT)) {
364         return;
365     }
366 
367     msg.sig = BTC_SIG_API_CB;
368     msg.pid = BTC_PID_GENERIC_CLIENT;
369     msg.act = act;
370 
371     btc_transfer_context(&msg, cb_params, cb_params == NULL ? 0 : sizeof(esp_ble_mesh_generic_client_cb_param_t),
372                          btc_ble_mesh_generic_client_copy_req_data, btc_ble_mesh_generic_client_free_req_data);
373 }
374 
bt_mesh_generic_client_cb_evt_to_btc(uint32_t opcode,uint8_t evt_type,struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,const uint8_t * val,size_t len)375 void bt_mesh_generic_client_cb_evt_to_btc(uint32_t opcode, uint8_t evt_type,
376                                           struct bt_mesh_model *model,
377                                           struct bt_mesh_msg_ctx *ctx,
378                                           const uint8_t *val, size_t len)
379 {
380     esp_ble_mesh_generic_client_cb_param_t cb_params = {0};
381     esp_ble_mesh_client_common_param_t params = {0};
382     uint8_t act = 0U;
383 
384     if (!model || !ctx) {
385         BT_ERR("%s, Invalid parameter", __func__);
386         return;
387     }
388 
389     switch (evt_type) {
390     case BTC_BLE_MESH_EVT_GENERIC_CLIENT_GET_STATE:
391         act = ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT;
392         break;
393     case BTC_BLE_MESH_EVT_GENERIC_CLIENT_SET_STATE:
394         act = ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT;
395         break;
396     case BTC_BLE_MESH_EVT_GENERIC_CLIENT_PUBLISH:
397         act = ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT;
398         break;
399     case BTC_BLE_MESH_EVT_GENERIC_CLIENT_TIMEOUT:
400         act = ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT;
401         break;
402     default:
403         BT_ERR("Unknown Generic client event type %d", evt_type);
404         return;
405     }
406 
407     params.opcode = opcode;
408     params.model = (esp_ble_mesh_model_t *)model;
409     params.ctx.net_idx = ctx->net_idx;
410     params.ctx.app_idx = ctx->app_idx;
411     params.ctx.addr = ctx->addr;
412     params.ctx.recv_ttl = ctx->recv_ttl;
413     params.ctx.recv_op = ctx->recv_op;
414     params.ctx.recv_dst = ctx->recv_dst;
415     params.ctx.recv_rssi = ctx->recv_rssi;
416     params.ctx.send_ttl = ctx->send_ttl;
417 
418     cb_params.error_code = 0;
419     cb_params.params = &params;
420 
421     if (val && len) {
422         memcpy(&cb_params.status_cb, val, MIN(len, sizeof(cb_params.status_cb)));
423     }
424 
425     btc_ble_mesh_generic_client_callback(&cb_params, act);
426     return;
427 }
428 
btc_ble_mesh_generic_client_publish_callback(uint32_t opcode,struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)429 void btc_ble_mesh_generic_client_publish_callback(uint32_t opcode, struct bt_mesh_model *model,
430                                                   struct bt_mesh_msg_ctx *ctx,
431                                                   struct net_buf_simple *buf)
432 {
433     if (!model || !ctx || !buf) {
434         BT_ERR("%s, Invalid parameter", __func__);
435         return;
436     }
437 
438     bt_mesh_generic_client_cb_evt_to_btc(opcode, BTC_BLE_MESH_EVT_GENERIC_CLIENT_PUBLISH,
439                                          model, ctx, buf->data, buf->len);
440     return;
441 }
442 
btc_ble_mesh_generic_client_call_handler(btc_msg_t * msg)443 void btc_ble_mesh_generic_client_call_handler(btc_msg_t *msg)
444 {
445     esp_ble_mesh_client_common_param_t *params = NULL;
446     btc_ble_mesh_generic_client_args_t *arg = NULL;
447     esp_ble_mesh_generic_client_cb_param_t cb = {0};
448     bt_mesh_client_common_param_t common = {0};
449 
450     if (!msg) {
451         BT_ERR("%s, Invalid parameter", __func__);
452         return;
453     }
454 
455     arg = (btc_ble_mesh_generic_client_args_t *)(msg->arg);
456 
457     switch (msg->act) {
458     case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE: {
459         params = arg->generic_client_get_state.params;
460         common.opcode = params->opcode;
461         common.model = (struct bt_mesh_model *)params->model;
462         common.ctx.net_idx = params->ctx.net_idx;
463         common.ctx.app_idx = params->ctx.app_idx;
464         common.ctx.addr = params->ctx.addr;
465         common.ctx.send_rel = params->ctx.send_rel;
466         common.ctx.send_ttl = params->ctx.send_ttl;
467         common.msg_timeout = params->msg_timeout;
468         common.msg_role = params->msg_role;
469 
470         cb.params = arg->generic_client_get_state.params;
471         cb.error_code = bt_mesh_generic_client_get_state(&common, arg->generic_client_get_state.get_state);
472         if (cb.error_code) {
473             /* If send failed, callback error_code to app layer immediately */
474             btc_ble_mesh_generic_client_callback(&cb, ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT);
475         }
476         break;
477     }
478     case BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE: {
479         params = arg->generic_client_set_state.params;
480         common.opcode = params->opcode;
481         common.model = (struct bt_mesh_model *)params->model;
482         common.ctx.net_idx = params->ctx.net_idx;
483         common.ctx.app_idx = params->ctx.app_idx;
484         common.ctx.addr = params->ctx.addr;
485         common.ctx.send_rel = params->ctx.send_rel;
486         common.ctx.send_ttl = params->ctx.send_ttl;
487         common.msg_timeout = params->msg_timeout;
488         common.msg_role = params->msg_role;
489 
490         cb.params = arg->generic_client_set_state.params;
491         cb.error_code = bt_mesh_generic_client_set_state(&common, arg->generic_client_set_state.set_state);
492         if (cb.error_code) {
493             /* If send failed, callback error_code to app layer immediately */
494             btc_ble_mesh_generic_client_callback(&cb, ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT);
495         }
496         break;
497     }
498     default:
499         break;
500     }
501 
502     btc_ble_mesh_generic_client_arg_deep_free(msg);
503     return;
504 }
505 
btc_ble_mesh_generic_client_cb_handler(btc_msg_t * msg)506 void btc_ble_mesh_generic_client_cb_handler(btc_msg_t *msg)
507 {
508     esp_ble_mesh_generic_client_cb_param_t *param = NULL;
509 
510     if (!msg) {
511         BT_ERR("%s, Invalid parameter", __func__);
512         return;
513     }
514 
515     param = (esp_ble_mesh_generic_client_cb_param_t *)(msg->arg);
516 
517     if (msg->act < ESP_BLE_MESH_GENERIC_CLIENT_EVT_MAX) {
518         btc_ble_mesh_generic_client_cb_to_app(msg->act, param);
519     } else {
520         BT_ERR("%s, Unknown act %d", __func__, msg->act);
521     }
522 
523     btc_ble_mesh_generic_client_free_req_data(msg);
524     return;
525 }
526 
527 #endif /* CONFIG_BLE_MESH_GENERIC_CLIENT */
528 
529 #if CONFIG_BLE_MESH_GENERIC_SERVER
530 
531 /* Generic Server Models related functions */
532 
btc_ble_mesh_generic_server_cb_to_app(esp_ble_mesh_generic_server_cb_event_t event,esp_ble_mesh_generic_server_cb_param_t * param)533 static inline void btc_ble_mesh_generic_server_cb_to_app(esp_ble_mesh_generic_server_cb_event_t event,
534                                                          esp_ble_mesh_generic_server_cb_param_t *param)
535 {
536     esp_ble_mesh_generic_server_cb_t btc_ble_mesh_cb =
537         (esp_ble_mesh_generic_server_cb_t)btc_profile_cb_get(BTC_PID_GENERIC_SERVER);
538     if (btc_ble_mesh_cb) {
539         btc_ble_mesh_cb(event, param);
540     }
541 }
542 
btc_ble_mesh_generic_server_copy_req_data(btc_msg_t * msg,void * p_dest,void * p_src)543 static void btc_ble_mesh_generic_server_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
544 {
545     esp_ble_mesh_generic_server_cb_param_t *p_dest_data = (esp_ble_mesh_generic_server_cb_param_t *)p_dest;
546     esp_ble_mesh_generic_server_cb_param_t *p_src_data = (esp_ble_mesh_generic_server_cb_param_t *)p_src;
547     uint16_t length = 0U;
548 
549     if (!msg || !p_src_data || !p_dest_data) {
550         BT_ERR("%s, Invalid parameter", __func__);
551         return;
552     }
553 
554     switch (msg->act) {
555     case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
556         switch (p_src_data->ctx.recv_op) {
557         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
558         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
559             if (p_src_data->value.state_change.user_property_set.value) {
560                 length = p_src_data->value.state_change.user_property_set.value->len;
561                 p_dest_data->value.state_change.user_property_set.value = bt_mesh_alloc_buf(length);
562                 if (p_dest_data->value.state_change.user_property_set.value == NULL) {
563                     BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
564                     return;
565                 }
566                 net_buf_simple_add_mem(p_dest_data->value.state_change.user_property_set.value,
567                                        p_src_data->value.state_change.user_property_set.value->data,
568                                        p_src_data->value.state_change.user_property_set.value->len);
569             }
570             break;
571         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
572         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
573             if (p_src_data->value.state_change.admin_property_set.value) {
574                 length = p_src_data->value.state_change.admin_property_set.value->len;
575                 p_dest_data->value.state_change.admin_property_set.value = bt_mesh_alloc_buf(length);
576                 if (p_dest_data->value.state_change.admin_property_set.value == NULL) {
577                     BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
578                     return;
579                 }
580                 net_buf_simple_add_mem(p_dest_data->value.state_change.admin_property_set.value,
581                                        p_src_data->value.state_change.admin_property_set.value->data,
582                                        p_src_data->value.state_change.admin_property_set.value->len);
583             }
584             break;
585         default:
586             break;
587         }
588         break;
589     case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
590         switch (p_src_data->ctx.recv_op) {
591         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
592         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
593             if (p_src_data->value.set.user_property.property_value) {
594                 length = p_src_data->value.set.user_property.property_value->len;
595                 p_dest_data->value.set.user_property.property_value = bt_mesh_alloc_buf(length);
596                 if (p_dest_data->value.set.user_property.property_value == NULL) {
597                     BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
598                     return;
599                 }
600                 net_buf_simple_add_mem(p_dest_data->value.set.user_property.property_value,
601                                        p_src_data->value.set.user_property.property_value->data,
602                                        p_src_data->value.set.user_property.property_value->len);
603             }
604             break;
605         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
606         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
607             if (p_src_data->value.set.admin_property.property_value) {
608                 length = p_src_data->value.set.admin_property.property_value->len;
609                 p_dest_data->value.set.admin_property.property_value = bt_mesh_alloc_buf(length);
610                 if (p_dest_data->value.set.admin_property.property_value == NULL) {
611                     BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
612                     return;
613                 }
614                 net_buf_simple_add_mem(p_dest_data->value.set.admin_property.property_value,
615                                        p_src_data->value.set.admin_property.property_value->data,
616                                        p_src_data->value.set.admin_property.property_value->len);
617             }
618             break;
619         default:
620             break;
621         }
622         break;
623     default:
624         break;
625     }
626 }
627 
btc_ble_mesh_generic_server_free_req_data(btc_msg_t * msg)628 static void btc_ble_mesh_generic_server_free_req_data(btc_msg_t *msg)
629 {
630     esp_ble_mesh_generic_server_cb_param_t *arg = NULL;
631 
632     if (!msg) {
633         BT_ERR("%s, Invalid parameter", __func__);
634         return;
635     }
636 
637     arg = (esp_ble_mesh_generic_server_cb_param_t *)(msg->arg);
638 
639     switch (msg->act) {
640     case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
641         switch (arg->ctx.recv_op) {
642         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
643         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
644             bt_mesh_free_buf(arg->value.state_change.user_property_set.value);
645             break;
646         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
647         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
648             bt_mesh_free_buf(arg->value.state_change.admin_property_set.value);
649             break;
650         default:
651             break;
652         }
653         break;
654     case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
655         switch (arg->ctx.recv_op) {
656         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
657         case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK:
658             bt_mesh_free_buf(arg->value.set.user_property.property_value);
659             break;
660         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
661         case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK:
662             bt_mesh_free_buf(arg->value.set.admin_property.property_value);
663             break;
664         default:
665             break;
666         }
667         break;
668     default:
669         break;
670     }
671 }
672 
btc_ble_mesh_generic_server_callback(esp_ble_mesh_generic_server_cb_param_t * cb_params,uint8_t act)673 static void btc_ble_mesh_generic_server_callback(esp_ble_mesh_generic_server_cb_param_t *cb_params, uint8_t act)
674 {
675     btc_msg_t msg = {0};
676 
677     BT_DBG("%s", __func__);
678 
679     /* If corresponding callback is not registered, event will not be posted. */
680     if (!btc_profile_cb_get(BTC_PID_GENERIC_SERVER)) {
681         return;
682     }
683 
684     msg.sig = BTC_SIG_API_CB;
685     msg.pid = BTC_PID_GENERIC_SERVER;
686     msg.act = act;
687 
688     btc_transfer_context(&msg, cb_params, cb_params == NULL ? 0 : sizeof(esp_ble_mesh_generic_server_cb_param_t),
689                          btc_ble_mesh_generic_server_copy_req_data, btc_ble_mesh_generic_server_free_req_data);
690 }
691 
bt_mesh_generic_server_cb_evt_to_btc(uint8_t evt_type,struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,const uint8_t * val,size_t len)692 void bt_mesh_generic_server_cb_evt_to_btc(uint8_t evt_type, struct bt_mesh_model *model,
693                                           struct bt_mesh_msg_ctx *ctx,
694                                           const uint8_t *val, size_t len)
695 {
696     esp_ble_mesh_generic_server_cb_param_t cb_params = {0};
697     uint8_t act = 0U;
698 
699     if (model == NULL || ctx == NULL) {
700         BT_ERR("%s, Invalid parameter", __func__);
701         return;
702     }
703 
704     switch (evt_type) {
705     case BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE:
706         act = ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT;
707         break;
708     case BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG:
709         act = ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT;
710         break;
711     case BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG:
712         act = ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT;
713         break;
714     default:
715         BT_ERR("Unknown Generic Server event type %d", evt_type);
716         return;
717     }
718 
719     cb_params.model = (esp_ble_mesh_model_t *)model;
720     cb_params.ctx.net_idx = ctx->net_idx;
721     cb_params.ctx.app_idx = ctx->app_idx;
722     cb_params.ctx.addr = ctx->addr;
723     cb_params.ctx.recv_ttl = ctx->recv_ttl;
724     cb_params.ctx.recv_op = ctx->recv_op;
725     cb_params.ctx.recv_dst = ctx->recv_dst;
726     cb_params.ctx.recv_rssi = ctx->recv_rssi;
727     cb_params.ctx.send_ttl = ctx->send_ttl;
728 
729     if (val && len) {
730         memcpy(&cb_params.value, val, MIN(len, sizeof(cb_params.value)));
731     }
732 
733     btc_ble_mesh_generic_server_callback(&cb_params, act);
734     return;
735 }
736 
btc_ble_mesh_generic_server_cb_handler(btc_msg_t * msg)737 void btc_ble_mesh_generic_server_cb_handler(btc_msg_t *msg)
738 {
739     esp_ble_mesh_generic_server_cb_param_t *param = NULL;
740 
741     if (!msg) {
742         BT_ERR("%s, Invalid parameter", __func__);
743         return;
744     }
745 
746     param = (esp_ble_mesh_generic_server_cb_param_t *)(msg->arg);
747 
748     if (msg->act < ESP_BLE_MESH_GENERIC_SERVER_EVT_MAX) {
749         btc_ble_mesh_generic_server_cb_to_app(msg->act, param);
750     } else {
751         BT_ERR("%s, Unknown act %d", __func__, msg->act);
752     }
753 
754     btc_ble_mesh_generic_server_free_req_data(msg);
755     return;
756 }
757 
758 #endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
759