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