1 /*
2  * SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
3  * SPDX-FileCopyrightText: 2015-2016 Intel Corporation
4  * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <string.h>
10 #include <errno.h>
11 
12 #include "bta/bta_api.h"
13 #include "bta/bta_gatt_api.h"
14 #include "bta/bta_gatt_common.h"
15 #include "bta_gattc_int.h"
16 #include "stack/btm_ble_api.h"
17 #include "p_256_ecc_pp.h"
18 #include "osi/future.h"
19 #include "device/controller.h"
20 
21 #include "mbedtls/aes.h"
22 
23 #include <tinycrypt/aes.h>
24 #include <tinycrypt/constants.h>
25 
26 #include "mesh_hci.h"
27 #include "mesh_bearer_adapt.h"
28 #include "mesh_common.h"
29 #include "provisioner_prov.h"
30 
31 struct bt_mesh_dev bt_mesh_dev;
32 
33 #define BLE_MESH_BTM_CHECK_STATUS(func) do {                                                     \
34         tBTM_STATUS __status = (func);                                                           \
35         if ((__status != BTM_SUCCESS) && (__status != BTM_CMD_STARTED)) {                        \
36             BT_ERR("%s, Invalid status %d", __func__, __status);                                 \
37             return -1;                                                                           \
38         }                                                                                        \
39     } while(0);
40 
41 #define BLE_MESH_GATT_GET_CONN_ID(conn_id)              (((uint16_t)(conn_id)) >> 8)
42 #define BLE_MESH_GATT_CREATE_CONN_ID(gatt_if, conn_id)  ((uint16_t)((((uint8_t)(conn_id)) << 8) | ((uint8_t)(gatt_if))))
43 
44 /* We don't need to manage the BLE_MESH_DEV_ADVERTISING flags in the version of Bluedroid,
45  * it will manage it in the BTM layer.
46  */
47 #define BLE_MESH_DEV    0
48 
49 /* P-256 Variables */
50 static uint8_t bt_mesh_public_key[64];
51 static BT_OCTET32 bt_mesh_private_key;
52 
53 /* Scan related functions */
54 static bt_mesh_scan_cb_t *bt_mesh_scan_dev_found_cb;
55 static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
56 
57 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
58     CONFIG_BLE_MESH_GATT_PROXY_SERVER
59 /* Using UUID with a fixed pattern 0x96 for BLE Mesh GATT Proxy Server */
60 #define BLE_MESH_GATTS_APP_UUID_BYTE     0x96
61 /* the gatt database list to save the attribute table */
62 static sys_slist_t bt_mesh_gatts_db;
63 
64 /* Static Variables */
65 static struct bt_mesh_conn bt_mesh_gatts_conn[BLE_MESH_MAX_CONN];
66 static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb;
67 static tBTA_GATTS_IF bt_mesh_gatts_if;
68 static BD_ADDR bt_mesh_gatts_addr;
69 static uint16_t svc_handle, char_handle;
70 static future_t *gatts_future_mesh;
71 
72 /* Static Functions */
73 static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(uint16_t handle);
74 #endif
75 
76 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
77     CONFIG_BLE_MESH_GATT_PROXY_CLIENT
78 /* Using UUID with a fixed pattern 0x97 for BLE Mesh GATT Proxy Client */
79 #define BLE_MESH_GATTC_APP_UUID_BYTE     0x97
80 static struct gattc_prov_info {
81     /* Service to be found depends on the type of adv pkt received */
82     struct bt_mesh_conn conn;
83     bt_mesh_addr_t addr;
84     uint16_t service_uuid;
85     uint16_t mtu;
86     bool     wr_desc_done;    /* Indicate if write char descriptor event is received */
87     uint16_t start_handle;    /* Service attribute start handle */
88     uint16_t end_handle;      /* Service attribute end handle */
89     uint16_t data_in_handle;  /* Data In Characteristic attribute handle */
90     uint16_t data_out_handle; /* Data Out Characteristic attribute handle */
91     uint16_t ccc_handle;      /* Data Out Characteristic CCC attribute handle */
92 } bt_mesh_gattc_info[BLE_MESH_MAX_CONN];
93 static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb;
94 static tBTA_GATTC_IF bt_mesh_gattc_if;
95 #endif
96 
bt_mesh_host_init(void)97 int bt_mesh_host_init(void)
98 {
99     return 0;
100 }
101 
bt_mesh_host_deinit(void)102 int bt_mesh_host_deinit(void)
103 {
104     return 0;
105 }
106 
bt_mesh_hci_init(void)107 void bt_mesh_hci_init(void)
108 {
109     const uint8_t *features = controller_get_interface()->get_features_ble()->as_array;
110     if (features != NULL) {
111         memcpy(bt_mesh_dev.features[0], features, 8);
112         memcpy(bt_mesh_dev.le.features, features, 8);
113     }
114 
115     /**
116      * Currently 20ms non-connectable adv interval is supported, and we need to add
117      * a flag to indicate this support.
118      */
119 #ifdef CONFIG_BLE_MESH_HCI_5_0
120     bt_mesh_dev.hci_version = BLE_MESH_HCI_VERSION_5_0;
121 #else
122     bt_mesh_dev.hci_version = controller_get_interface()->get_bt_version()->hci_version;
123 #endif
124     bt_mesh_dev.lmp_version = controller_get_interface()->get_bt_version()->lmp_version;
125     bt_mesh_dev.hci_revision = controller_get_interface()->get_bt_version()->hci_revision;
126     bt_mesh_dev.lmp_subversion = controller_get_interface()->get_bt_version()->lmp_subversion;
127     bt_mesh_dev.manufacturer = controller_get_interface()->get_bt_version()->manufacturer;
128 
129     const uint8_t *p = controller_get_interface()->get_ble_supported_states();
130     uint64_t states_fh = 0, states_sh = 0;
131     STREAM_TO_UINT32(states_fh, p);
132     STREAM_TO_UINT32(states_sh, p);
133     bt_mesh_dev.le.states = (states_sh << 32) | states_fh;
134 }
135 
bt_mesh_scan_results_change_2_bta(tBTM_INQ_RESULTS * p_inq,uint8_t * p_eir,tBTA_DM_SEARCH_CBACK * p_scan_cback)136 static void bt_mesh_scan_results_change_2_bta(tBTM_INQ_RESULTS *p_inq, uint8_t *p_eir,
137                                               tBTA_DM_SEARCH_CBACK *p_scan_cback)
138 {
139     tBTM_INQ_INFO *p_inq_info = NULL;
140     tBTA_DM_SEARCH result = {0};
141 
142     bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
143     result.inq_res.rssi = p_inq->rssi;
144     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
145     result.inq_res.inq_result_type  = p_inq->inq_result_type;
146     result.inq_res.device_type      = p_inq->device_type;
147     result.inq_res.flag             = p_inq->flag;
148     result.inq_res.adv_data_len     = p_inq->adv_data_len;
149     result.inq_res.scan_rsp_len     = p_inq->scan_rsp_len;
150     memcpy(result.inq_res.dev_class, p_inq->dev_class, sizeof(DEV_CLASS));
151     result.inq_res.ble_evt_type     = p_inq->ble_evt_type;
152 
153     /* application will parse EIR to find out remote device name */
154     result.inq_res.p_eir = p_eir;
155 
156     if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
157         /* initialize remt_name_not_required to FALSE so that we get the name by default */
158         result.inq_res.remt_name_not_required = FALSE;
159     }
160 
161     if (p_scan_cback) {
162         p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
163     }
164 
165     if (p_inq_info) {
166         /* application indicates if it knows the remote name, inside the callback
167          copy that to the inquiry data base*/
168         if (result.inq_res.remt_name_not_required) {
169             p_inq_info->appl_knows_rem_name = TRUE;
170         }
171     }
172 }
173 
bt_mesh_scan_results_cb(tBTM_INQ_RESULTS * p_inq,uint8_t * p_eir)174 static void bt_mesh_scan_results_cb(tBTM_INQ_RESULTS *p_inq, uint8_t *p_eir)
175 {
176     bt_mesh_scan_results_change_2_bta(p_inq, p_eir, bt_mesh_scan_result_callback);
177 }
178 
valid_adv_param(const struct bt_mesh_adv_param * param)179 static bool valid_adv_param(const struct bt_mesh_adv_param *param)
180 {
181     if (!(param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
182 #if BLE_MESH_DEV
183         if (bt_mesh_dev.hci_version < BLE_MESH_HCI_VERSION_5_0 &&
184                 param->interval_min < 0x00a0) {
185             return false;
186         }
187 #endif
188     }
189 
190     if (param->interval_min > param->interval_max ||
191             param->interval_min < 0x0020 || param->interval_max > 0x4000) {
192         return false;
193     }
194 
195     return true;
196 }
197 
set_adv_data(uint16_t hci_op,const struct bt_mesh_adv_data * ad,size_t ad_len)198 static int set_adv_data(uint16_t hci_op, const struct bt_mesh_adv_data *ad, size_t ad_len)
199 {
200     struct bt_mesh_hci_cp_set_adv_data param = {0};
201     int i;
202 
203     if (ad == NULL || ad_len == 0) {
204         return 0;
205     }
206 
207     for (i = 0; i < ad_len; i++) {
208         /* Check if ad fit in the remaining buffer */
209         if (param.len + ad[i].data_len + 2 > 31) {
210             return -EINVAL;
211         }
212 
213         param.data[param.len++] = ad[i].data_len + 1;
214         param.data[param.len++] = ad[i].type;
215 
216         memcpy(&param.data[param.len], ad[i].data, ad[i].data_len);
217         param.len += ad[i].data_len;
218     }
219 
220     /* Set adv data and scan rsp data. */
221     if (hci_op == BLE_MESH_HCI_OP_SET_ADV_DATA) {
222         BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteAdvDataRaw(param.data, param.len));
223     } else if (hci_op == BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA) {
224         BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteScanRspRaw(param.data, param.len));
225     }
226 
227     return 0;
228 }
229 
start_adv_completed_cb(uint8_t status)230 static void start_adv_completed_cb(uint8_t status)
231 {
232 #if BLE_MESH_DEV
233     if (!status) {
234         bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
235     }
236 #endif
237 }
238 
valid_scan_param(const struct bt_mesh_scan_param * param)239 static bool valid_scan_param(const struct bt_mesh_scan_param *param)
240 {
241     if (param->type != BLE_MESH_SCAN_PASSIVE &&
242             param->type != BLE_MESH_SCAN_ACTIVE) {
243         return false;
244     }
245 
246     if (param->filter_dup != BLE_MESH_SCAN_FILTER_DUP_DISABLE &&
247             param->filter_dup != BLE_MESH_SCAN_FILTER_DUP_ENABLE) {
248         return false;
249     }
250 
251     if (param->interval < 0x0004 || param->interval > 0x4000) {
252         return false;
253     }
254 
255     if (param->window < 0x0004 || param->window > 0x4000) {
256         return false;
257     }
258 
259     if (param->window > param->interval) {
260         return false;
261     }
262 
263     return true;
264 }
265 
start_le_scan(uint8_t scan_type,uint16_t interval,uint16_t window,uint8_t filter_dup,uint8_t scan_fil_policy)266 static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
267                          uint8_t filter_dup, uint8_t scan_fil_policy)
268 {
269     UINT8 addr_type_own = BLE_MESH_ADDR_PUBLIC;  /* Currently only support Public Address */
270     tGATT_IF client_if = 0xFF; /* Default GATT interface id */
271 
272     BLE_MESH_BTM_CHECK_STATUS(
273         BTM_BleSetScanFilterParams(client_if, interval, window, scan_type, addr_type_own,
274                                    filter_dup, scan_fil_policy, NULL));
275 
276     /* BLE Mesh scan permanently, so no duration of scan here */
277     BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(true, 0, bt_mesh_scan_results_cb, NULL, NULL));
278 
279 #if BLE_MESH_DEV
280     if (scan_type == BLE_MESH_SCAN_ACTIVE) {
281         bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ACTIVE_SCAN);
282     } else {
283         bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ACTIVE_SCAN);
284     }
285 #endif
286 
287     return 0;
288 }
289 
bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event,tBTA_DM_SEARCH * p_data)290 static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
291 {
292     struct net_buf_simple buf = {0};
293     bt_mesh_addr_t addr = {0};
294 
295     BT_DBG("%s, event %d", __func__, event);
296 
297     if (event == BTA_DM_INQ_RES_EVT) {
298         /* TODO: How to process scan response here? PS: p_data->inq_res.scan_rsp_len */
299         addr.type = p_data->inq_res.ble_addr_type;
300         memcpy(addr.val, p_data->inq_res.bd_addr, BLE_MESH_ADDR_LEN);
301 
302         net_buf_simple_init_with_data(&buf, p_data->inq_res.p_eir, p_data->inq_res.adv_data_len);
303 
304         if (bt_mesh_scan_dev_found_cb) {
305             bt_mesh_scan_dev_found_cb(&addr, p_data->inq_res.rssi, p_data->inq_res.ble_evt_type, &buf);
306         }
307     } else if (event == BTA_DM_INQ_CMPL_EVT) {
308         BT_INFO("Scan completed, number of scan response %d", p_data->inq_cmpl.num_resps);
309     } else {
310         BT_WARN("Unexpected scan result event %d", event);
311     }
312 }
313 
314 /* APIs functions */
bt_le_adv_start(const struct bt_mesh_adv_param * param,const struct bt_mesh_adv_data * ad,size_t ad_len,const struct bt_mesh_adv_data * sd,size_t sd_len)315 int bt_le_adv_start(const struct bt_mesh_adv_param *param,
316                     const struct bt_mesh_adv_data *ad, size_t ad_len,
317                     const struct bt_mesh_adv_data *sd, size_t sd_len)
318 {
319     tBTA_START_ADV_CMPL_CBACK *p_start_adv_cb = NULL;
320     tBTM_BLE_ADV_CHNL_MAP channel_map = 0U;
321     tBLE_ADDR_TYPE addr_type_own = 0U;
322     tBLE_BD_ADDR p_dir_bda = {0};
323     tBTM_BLE_AFP adv_fil_pol = 0U;
324     uint16_t interval = 0U;
325     uint8_t adv_type = 0U;
326     int err = 0;
327 
328 #if BLE_MESH_DEV
329     if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
330         return -EALREADY;
331     }
332 #endif
333 
334     if (!valid_adv_param(param)) {
335         BT_ERR("Invalid adv parameters");
336         return -EINVAL;
337     }
338 
339     err = set_adv_data(BLE_MESH_HCI_OP_SET_ADV_DATA, ad, ad_len);
340     if (err) {
341         BT_ERR("Failed to set adv data");
342         return err;
343     }
344 
345     /*
346      * We need to set SCAN_RSP when enabling advertising type that allows
347      * for Scan Requests.
348      *
349      * If sd was not provided but we enable connectable undirected
350      * advertising sd needs to be cleared from values set by previous calls.
351      * Clearing sd is done by calling set_adv_data() with NULL data and zero len.
352      * So following condition check is unusual but correct.
353      */
354     if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
355         err = set_adv_data(BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA, sd, sd_len);
356         if (err) {
357             BT_ERR("Failed to set scan rsp data");
358             return err;
359         }
360     }
361 
362     if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) {
363         adv_type = BLE_MESH_ADV_IND;
364     } else if (sd != NULL) {
365         adv_type = BLE_MESH_ADV_SCAN_IND;
366     } else {
367         adv_type = BLE_MESH_ADV_NONCONN_IND;
368     }
369     addr_type_own = BLE_MESH_ADDR_PUBLIC; /* Currently only support Public Address */
370     channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
371     adv_fil_pol = BLE_MESH_AP_SCAN_CONN_ALL;
372     p_start_adv_cb = start_adv_completed_cb;
373 
374     interval = param->interval_min;
375 
376 #if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL
377     /* If non-connectable mesh packets are transmitted with an adv interval
378      * not smaller than 10ms, then we will use a random adv interval between
379      * [interval / 2, interval] for them.
380      */
381     if (adv_type == BLE_MESH_ADV_NONCONN_IND && interval >= 16) {
382         interval >>= 1;
383         interval += (bt_mesh_get_rand() % (interval + 1));
384 
385         BT_INFO("%u->%u", param->interval_min, interval);
386     }
387 #endif
388 
389     /* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
390     BLE_MESH_BTM_CHECK_STATUS(
391         BTM_BleSetAdvParamsAll(interval, interval, adv_type,
392                                addr_type_own, &p_dir_bda,
393                                channel_map, adv_fil_pol, p_start_adv_cb));
394     BLE_MESH_BTM_CHECK_STATUS(BTM_BleStartAdv());
395 
396 #if BLE_MESH_DEV
397     bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
398 
399     if (!(param->options & BLE_MESH_ADV_OPT_ONE_TIME)) {
400         bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
401     }
402 #endif
403 
404     return 0;
405 }
406 
407 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param * param,const struct bt_mesh_ble_adv_data * data)408 int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
409                           const struct bt_mesh_ble_adv_data *data)
410 {
411     struct bt_mesh_hci_cp_set_adv_data set = {0};
412     tBTM_BLE_ADV_CHNL_MAP channel_map = 0U;
413     tBTM_BLE_AFP adv_fil_pol = 0U;
414     tBLE_BD_ADDR p_dir_bda = {0};
415 
416     if (data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
417         param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
418         if (data->adv_data_len) {
419             set.len = data->adv_data_len;
420             memcpy(set.data, data->adv_data, data->adv_data_len);
421             BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteAdvDataRaw(set.data, set.len));
422         }
423         if (data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
424             set.len = data->scan_rsp_data_len;
425             memcpy(set.data, data->scan_rsp_data, data->scan_rsp_data_len);
426             BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteScanRspRaw(set.data, set.len));
427         }
428     }
429 
430     channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
431     adv_fil_pol = BLE_MESH_AP_SCAN_CONN_ALL;
432     if (param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
433         param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
434         param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
435         param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
436         p_dir_bda.type = param->peer_addr_type;
437         memcpy(p_dir_bda.bda, param->peer_addr, BLE_MESH_ADDR_LEN);
438     }
439 
440     /* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
441     BLE_MESH_BTM_CHECK_STATUS(
442         BTM_BleSetAdvParamsAll(param->interval, param->interval, param->adv_type,
443                                param->own_addr_type, &p_dir_bda,
444                                channel_map, adv_fil_pol, NULL));
445     BLE_MESH_BTM_CHECK_STATUS(BTM_BleStartAdv());
446 
447     return 0;
448 }
449 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
450 
bt_le_adv_stop(void)451 int bt_le_adv_stop(void)
452 {
453 #if BLE_MESH_DEV
454     bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
455     if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
456         return 0;
457     }
458 #endif
459 
460     BLE_MESH_BTM_CHECK_STATUS(BTM_BleBroadcast(false, NULL));
461 
462 #if BLE_MESH_DEV
463     bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
464 #endif
465 
466     return 0;
467 }
468 
bt_le_scan_start(const struct bt_mesh_scan_param * param,bt_mesh_scan_cb_t cb)469 int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb)
470 {
471     int err = 0;
472 
473     if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
474         BT_INFO("Scan is already started");
475         return -EALREADY;
476     }
477 
478     if (!valid_scan_param(param)) {
479         return -EINVAL;
480     }
481 
482 #if BLE_MESH_DEV
483     if (param->filter_dup) {
484         bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCAN_FILTER_DUP);
485     } else {
486         bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCAN_FILTER_DUP);
487     }
488 #endif
489 
490     err = start_le_scan(param->type, param->interval, param->window,
491                         param->filter_dup, param->scan_fil_policy);
492     if (err) {
493         return err;
494     }
495 
496     bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
497     bt_mesh_scan_dev_found_cb = cb;
498 
499     return 0;
500 }
501 
bt_le_scan_stop(void)502 int bt_le_scan_stop(void)
503 {
504     if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
505         BT_INFO("Scan is already stopped");
506         return -EALREADY;
507     }
508 
509     BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(false, 0, NULL, NULL, NULL));
510 
511     bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
512     bt_mesh_scan_dev_found_cb = NULL;
513 
514     return 0;
515 }
516 
517 #if CONFIG_BLE_MESH_TEST_USE_WHITE_LIST
bt_le_update_white_list(struct bt_mesh_white_list * wl)518 int bt_le_update_white_list(struct bt_mesh_white_list *wl)
519 {
520     if (wl == NULL) {
521         BT_ERR("%s, Invalid parameter", __func__);
522         return -EINVAL;
523     }
524 
525     if (BTM_BleUpdateAdvWhitelist(wl->add_remove, wl->remote_bda,
526             wl->addr_type, (tBTM_UPDATE_WHITELIST_CBACK *)wl->update_wl_comp_cb) == false) {
527         return -EIO;
528     }
529 
530     return 0;
531 }
532 #endif
533 
534 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
535     CONFIG_BLE_MESH_GATT_PROXY_SERVER
bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event,tBTA_GATTS * p_data)536 static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
537 {
538     switch (event) {
539     case BTA_GATTS_REG_EVT:
540         if (p_data->reg_oper.status == BTA_GATT_OK) {
541             bt_mesh_gatts_if = p_data->reg_oper.server_if;
542             future_ready(gatts_future_mesh, FUTURE_SUCCESS);
543         } else {
544             future_ready(gatts_future_mesh, FUTURE_FAIL);
545         }
546         break;
547     case BTA_GATTS_READ_EVT: {
548         struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(p_data->req_data.p_data->read_req.handle);
549         uint8_t index = BLE_MESH_GATT_GET_CONN_ID(p_data->req_data.conn_id);
550         tBTA_GATTS_RSP rsp = {0};
551         uint8_t buf[100] = {0};
552         uint16_t len = 0;
553 
554         BT_DBG("gatts read, handle %d", p_data->req_data.p_data->read_req.handle);
555 
556         if (attr != NULL && attr->read != NULL) {
557             if ((len = attr->read(&bt_mesh_gatts_conn[index], attr, buf, 100,
558                                   p_data->req_data.p_data->read_req.offset)) > 0) {
559                 rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle;
560                 rsp.attr_value.len = len;
561                 memcpy(&rsp.attr_value.value[0], buf, len);
562                 BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
563                                   p_data->req_data.status, &rsp);
564                 BT_DBG("Send gatts read rsp, handle %d", attr->handle);
565             } else {
566                 BT_WARN("Mesh gatts read failed");
567             }
568         }
569         break;
570     }
571     case BTA_GATTS_WRITE_EVT: {
572         struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(p_data->req_data.p_data->write_req.handle);
573         uint8_t index = BLE_MESH_GATT_GET_CONN_ID(p_data->req_data.conn_id);
574         uint16_t len = 0;
575 
576         BT_DBG("gatts write, handle %d, len %d, data %s", p_data->req_data.p_data->write_req.handle,
577                p_data->req_data.p_data->write_req.len,
578                bt_hex(p_data->req_data.p_data->write_req.value, p_data->req_data.p_data->write_req.len));
579 
580         if (attr != NULL && attr->write != NULL) {
581             if ((len = attr->write(&bt_mesh_gatts_conn[index], attr,
582                                    p_data->req_data.p_data->write_req.value,
583                                    p_data->req_data.p_data->write_req.len,
584                                    p_data->req_data.p_data->write_req.offset, 0)) > 0) {
585                 if (p_data->req_data.p_data->write_req.need_rsp) {
586                     BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
587                                       p_data->req_data.status, NULL);
588                     BT_DBG("Send gatts write rsp, handle %d", attr->handle);
589                 }
590             }
591         }
592         break;
593     }
594     case BTA_GATTS_EXEC_WRITE_EVT:
595         break;
596     case BTA_GATTS_MTU_EVT:
597         break;
598     case BTA_GATTS_CONF_EVT:
599         break;
600     case BTA_GATTS_CREATE_EVT:
601         svc_handle = p_data->create.service_id;
602         BT_DBG("svc_handle %d, gatts_future_mesh %p", svc_handle, gatts_future_mesh);
603         if (gatts_future_mesh != NULL) {
604             future_ready(gatts_future_mesh, FUTURE_SUCCESS);
605         }
606         break;
607     case BTA_GATTS_ADD_INCL_SRVC_EVT:
608         svc_handle = p_data->add_result.attr_id;
609         if (gatts_future_mesh != NULL) {
610             future_ready(gatts_future_mesh, FUTURE_SUCCESS);
611         }
612         break;
613     case BTA_GATTS_ADD_CHAR_EVT:
614         char_handle = p_data->add_result.attr_id;
615         if (gatts_future_mesh != NULL) {
616             future_ready(gatts_future_mesh, FUTURE_SUCCESS);
617         }
618         break;
619     case BTA_GATTS_ADD_CHAR_DESCR_EVT:
620         char_handle = p_data->add_result.attr_id;
621         if (gatts_future_mesh != NULL) {
622             future_ready(gatts_future_mesh, FUTURE_SUCCESS);
623         }
624         break;
625     case BTA_GATTS_DELELTE_EVT:
626         break;
627     case BTA_GATTS_START_EVT:
628         break;
629     case BTA_GATTS_STOP_EVT:
630         break;
631     case BTA_GATTS_CONNECT_EVT:
632 #if BLE_MESH_DEV
633         /* When connection is created, advertising will be stopped automatically. */
634         bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
635 #endif
636         if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->connected != NULL) {
637             uint8_t index = BLE_MESH_GATT_GET_CONN_ID(p_data->conn.conn_id);
638             if (index < BLE_MESH_MAX_CONN) {
639                 bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(p_data->conn.conn_id);
640                 (bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
641             }
642             memcpy(bt_mesh_gatts_addr, p_data->conn.remote_bda, BLE_MESH_ADDR_LEN);
643             /* This is for EspBleMesh Android app. When it tries to connect with the
644              * device at the first time and it fails due to some reason. And after
645              * the second connection, the device needs to send GATT service change
646              * indication to the phone manually to notify it discovering service again.
647              */
648             BTA_GATTS_SendServiceChangeIndication(bt_mesh_gatts_if, bt_mesh_gatts_addr);
649         }
650         break;
651     case BTA_GATTS_DISCONNECT_EVT:
652 #if BLE_MESH_DEV
653         bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
654 #endif
655         if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->disconnected != NULL) {
656             uint8_t index = BLE_MESH_GATT_GET_CONN_ID(p_data->conn.conn_id);
657             if (index < BLE_MESH_MAX_CONN) {
658                 bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(p_data->conn.conn_id);
659                 (bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], p_data->conn.reason);
660             }
661             memset(bt_mesh_gatts_addr, 0x0, BLE_MESH_ADDR_LEN);
662         }
663         break;
664     case BTA_GATTS_CLOSE_EVT:
665         break;
666     default:
667         break;
668     }
669 }
670 
bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb * cb)671 void bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb *cb)
672 {
673     bt_mesh_gatts_conn_cb = cb;
674 }
675 
bt_mesh_gatts_conn_cb_deregister(void)676 void bt_mesh_gatts_conn_cb_deregister(void)
677 {
678     bt_mesh_gatts_conn_cb = NULL;
679 }
680 
bt_mesh_gatts_find_attr_by_handle(uint16_t handle)681 static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(uint16_t handle)
682 {
683     struct bt_mesh_gatt_service *svc = NULL;
684     struct bt_mesh_gatt_attr *attr = NULL;
685 
686     SYS_SLIST_FOR_EACH_CONTAINER(&bt_mesh_gatts_db, svc, node) {
687         int i;
688 
689         for (i = 0; i < svc->attr_count; i++) {
690             attr = &svc->attrs[i];
691             /* Check the attrs handle is equal to the handle or not */
692             if (attr->handle == handle) {
693                 return attr;
694             }
695         }
696     }
697 
698     return NULL;
699 }
700 
bt_mesh_gatts_foreach_attr(uint16_t start_handle,uint16_t end_handle,bt_mesh_gatt_attr_func_t func,void * user_data)701 static void bt_mesh_gatts_foreach_attr(uint16_t start_handle, uint16_t end_handle,
702                                        bt_mesh_gatt_attr_func_t func, void *user_data)
703 {
704     struct bt_mesh_gatt_service *svc = NULL;
705 
706     SYS_SLIST_FOR_EACH_CONTAINER(&bt_mesh_gatts_db, svc, node) {
707         int i;
708 
709         for (i = 0; i < svc->attr_count; i++) {
710             struct bt_mesh_gatt_attr *attr = &svc->attrs[i];
711 
712             /* Check if attribute handle is within range */
713             if (attr->handle < start_handle ||
714                     attr->handle > end_handle) {
715                 continue;
716             }
717 
718             if (func(attr, user_data) == BLE_MESH_GATT_ITER_STOP) {
719                 return;
720             }
721         }
722     }
723 }
724 
find_next(const struct bt_mesh_gatt_attr * attr,void * user_data)725 static uint8_t find_next(const struct bt_mesh_gatt_attr *attr, void *user_data)
726 {
727     struct bt_mesh_gatt_attr **next = user_data;
728 
729     *next = (struct bt_mesh_gatt_attr *)attr;
730 
731     return BLE_MESH_GATT_ITER_STOP;
732 }
733 
bt_mesh_gatts_attr_next(const struct bt_mesh_gatt_attr * attr)734 static struct bt_mesh_gatt_attr *bt_mesh_gatts_attr_next(const struct bt_mesh_gatt_attr *attr)
735 {
736     struct bt_mesh_gatt_attr *next = NULL;
737 
738     bt_mesh_gatts_foreach_attr(attr->handle + 1, attr->handle + 1, find_next, &next);
739 
740     return next;
741 }
742 
bt_mesh_gatts_attr_read(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,void * buf,uint16_t buf_len,uint16_t offset,const void * value,uint16_t value_len)743 ssize_t bt_mesh_gatts_attr_read(struct bt_mesh_conn *conn,
744                                 const struct bt_mesh_gatt_attr *attr,
745                                 void *buf, uint16_t buf_len, uint16_t offset,
746                                 const void *value, uint16_t value_len)
747 {
748     uint16_t len = 0U;
749 
750     if (offset > value_len) {
751         return BLE_MESH_GATT_ERR(BLE_MESH_ATT_ERR_INVALID_OFFSET);
752     }
753 
754     len = MIN(buf_len, value_len - offset);
755 
756     BT_DBG("handle 0x%04x offset %u length %u", attr->handle, offset, len);
757 
758     memcpy(buf, value + offset, len);
759 
760     return len;
761 }
762 
763 struct gatts_incl {
764     uint16_t start_handle;
765     uint16_t end_handle;
766     uint16_t uuid16;
767 } __packed;
768 
bt_mesh_gatts_attr_read_included(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)769 ssize_t bt_mesh_gatts_attr_read_included(struct bt_mesh_conn *conn,
770                                          const struct bt_mesh_gatt_attr *attr,
771                                          void *buf, uint16_t len, uint16_t offset)
772 {
773     struct bt_mesh_gatt_attr *incl = attr->user_data;
774     struct bt_mesh_uuid *uuid = incl->user_data;
775     struct gatts_incl pdu = {0};
776     uint8_t value_len = 0U;
777 
778     /* First attr points to the start handle */
779     pdu.start_handle = sys_cpu_to_le16(incl->handle);
780     value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle);
781 
782     /*
783      * Core 4.2, Vol 3, Part G, 3.2,
784      * The Service UUID shall only be present when the UUID is a 16-bit Bluetooth UUID.
785      */
786     if (uuid->type == BLE_MESH_UUID_TYPE_16) {
787         pdu.uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(uuid)->val);
788         value_len += sizeof(pdu.uuid16);
789     }
790 
791     return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
792 }
793 
bt_mesh_gatts_attr_read_service(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)794 ssize_t bt_mesh_gatts_attr_read_service(struct bt_mesh_conn *conn,
795                                         const struct bt_mesh_gatt_attr *attr,
796                                         void *buf, uint16_t len, uint16_t offset)
797 {
798     struct bt_mesh_uuid *uuid = attr->user_data;
799 
800     if (uuid->type == BLE_MESH_UUID_TYPE_16) {
801         uint16_t uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(uuid)->val);
802 
803         return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &uuid16, 2);
804     }
805 
806     return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset,
807                                    BLE_MESH_UUID_128(uuid)->val, 16);
808 }
809 
810 struct gatts_chrc {
811     uint8_t  properties;
812     uint16_t value_handle;
813     union {
814         uint16_t uuid16;
815         uint8_t  uuid[16];
816     };
817 } __packed;
818 
bt_mesh_gatts_attr_read_chrc(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)819 ssize_t bt_mesh_gatts_attr_read_chrc(struct bt_mesh_conn *conn,
820                                      const struct bt_mesh_gatt_attr *attr,
821                                      void *buf, uint16_t len, uint16_t offset)
822 {
823     struct bt_mesh_gatt_char *chrc = attr->user_data;
824     const struct bt_mesh_gatt_attr *next = NULL;
825     struct gatts_chrc pdu = {0};
826     uint8_t value_len = 0U;
827 
828     pdu.properties = chrc->properties;
829     /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 534:
830      * 3.3.2 Characteristic Value Declaration
831      * The Characteristic Value declaration contains the value of the
832      * characteristic. It is the first Attribute after the characteristic
833      * declaration. All characteristic definitions shall have a
834      * Characteristic Value declaration.
835      */
836     next = bt_mesh_gatts_attr_next(attr);
837     if (!next) {
838         BT_WARN("No value for characteristic, handle 0x%04x", attr->handle);
839         pdu.value_handle = 0x0000;
840     } else {
841         pdu.value_handle = sys_cpu_to_le16(next->handle);
842     }
843     value_len = sizeof(pdu.properties) + sizeof(pdu.value_handle);
844 
845     if (chrc->uuid->type == BLE_MESH_UUID_TYPE_16) {
846         pdu.uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(chrc->uuid)->val);
847         value_len += 2;
848     } else {
849         memcpy(pdu.uuid, BLE_MESH_UUID_128(chrc->uuid)->val, 16);
850         value_len += 16;
851     }
852 
853     return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
854 }
855 
bta_uuid_to_bt_mesh_uuid(tBT_UUID * bta_uuid,const struct bt_mesh_uuid * uuid)856 static void bta_uuid_to_bt_mesh_uuid(tBT_UUID *bta_uuid, const struct bt_mesh_uuid  *uuid)
857 {
858     assert(uuid != NULL && bta_uuid != NULL);
859 
860     if (uuid->type == BLE_MESH_UUID_TYPE_16) {
861         bta_uuid->len = LEN_UUID_16;
862         bta_uuid->uu.uuid16 = BLE_MESH_UUID_16(uuid)->val;
863     } else if (uuid->type == BLE_MESH_UUID_TYPE_32) {
864         bta_uuid->len = LEN_UUID_32;
865         bta_uuid->uu.uuid32 = BLE_MESH_UUID_32(uuid)->val;
866     } else if (uuid->type == BLE_MESH_UUID_TYPE_128) {
867         bta_uuid->len = LEN_UUID_128;
868         memcpy(bta_uuid->uu.uuid128, BLE_MESH_UUID_128(uuid)->val, LEN_UUID_128);
869     } else {
870         BT_ERR("Invalid mesh uuid type %d", uuid->type);
871     }
872 
873     return;
874 }
875 
gatts_register(struct bt_mesh_gatt_service * svc)876 static int gatts_register(struct bt_mesh_gatt_service *svc)
877 {
878     struct bt_mesh_gatt_service *last = NULL;
879     uint16_t handle = 0U;
880 
881     if (sys_slist_is_empty(&bt_mesh_gatts_db)) {
882         handle = 0;
883         goto populate;
884     }
885 
886     last = SYS_SLIST_PEEK_TAIL_CONTAINER(&bt_mesh_gatts_db, last, node);
887     handle = last->attrs[last->attr_count - 1].handle;
888     BT_DBG("gatts register, handle %d", handle);
889 
890     ((void) handle);
891 
892 populate:
893     sys_slist_append(&bt_mesh_gatts_db, &svc->node);
894     return 0;
895 }
896 
gatts_deregister(struct bt_mesh_gatt_service * svc)897 static int gatts_deregister(struct bt_mesh_gatt_service *svc)
898 {
899     if (sys_slist_is_empty(&bt_mesh_gatts_db)) {
900         return 0;
901     }
902 
903     sys_slist_find_and_remove(&bt_mesh_gatts_db, &svc->node);
904     return 0;
905 }
906 
bt_mesh_perm_to_bta_perm(uint8_t perm)907 static tBTA_GATT_PERM bt_mesh_perm_to_bta_perm(uint8_t perm)
908 {
909     tBTA_GATT_PERM bta_perm = 0;
910 
911     if ((perm & BLE_MESH_GATT_PERM_READ) == BLE_MESH_GATT_PERM_READ) {
912         bta_perm |= BTA_GATT_PERM_READ;
913     }
914 
915     if ((perm & BLE_MESH_GATT_PERM_WRITE) == BLE_MESH_GATT_PERM_WRITE) {
916         bta_perm |= BTA_GATT_PERM_WRITE;
917     }
918 
919     if ((perm & BLE_MESH_GATT_PERM_READ_ENCRYPT) ==  BLE_MESH_GATT_PERM_READ_ENCRYPT) {
920         bta_perm |= BTA_GATT_PERM_READ_ENCRYPTED;
921     }
922 
923     if ((perm & BLE_MESH_GATT_PERM_WRITE_ENCRYPT) == BLE_MESH_GATT_PERM_WRITE_ENCRYPT) {
924         bta_perm |= BTA_GATT_PERM_WRITE_ENCRYPTED;
925     }
926 
927     if ((perm & BLE_MESH_GATT_PERM_READ_AUTHEN) == BLE_MESH_GATT_PERM_READ_AUTHEN) {
928         bta_perm |= BTA_GATT_PERM_READ_ENC_MITM;
929     }
930 
931     if ((perm & BLE_MESH_GATT_PERM_WRITE_AUTHEN) == BLE_MESH_GATT_PERM_WRITE_AUTHEN) {
932         bta_perm |= BTA_GATT_PERM_WRITE_ENC_MITM;
933     }
934 
935     return bta_perm;
936 }
937 
bt_mesh_gatts_service_register(struct bt_mesh_gatt_service * svc)938 int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc)
939 {
940     tBT_UUID bta_uuid = {0};
941 
942     assert(svc != NULL);
943 
944     for (int i = 0; i < svc->attr_count; i++) {
945         if (svc->attrs[i].uuid->type == BLE_MESH_UUID_TYPE_16) {
946             switch (BLE_MESH_UUID_16(svc->attrs[i].uuid)->val) {
947             case BLE_MESH_UUID_GATT_PRIMARY_VAL: {
948                 gatts_future_mesh = future_new();
949                 bta_uuid_to_bt_mesh_uuid(&bta_uuid, (struct bt_mesh_uuid *)svc->attrs[i].user_data);
950                 BTA_GATTS_CreateService(bt_mesh_gatts_if,
951                                         &bta_uuid, 0, svc->attr_count, true);
952                 if (future_await(gatts_future_mesh) == FUTURE_FAIL) {
953                     BT_ERR("Failed to add primary service");
954                     return ESP_FAIL;
955                 }
956                 svc->attrs[i].handle = svc_handle;
957                 BT_DBG("Add primary service, uuid 0x%04x, perm %d, handle %d",
958                         bta_uuid.uu.uuid16, svc->attrs[i].perm, svc_handle);
959                 break;
960             }
961             case BLE_MESH_UUID_GATT_SECONDARY_VAL: {
962                 gatts_future_mesh = future_new();
963                 bta_uuid_to_bt_mesh_uuid(&bta_uuid, (struct bt_mesh_uuid *)svc->attrs[i].user_data);
964                 BTA_GATTS_CreateService(bt_mesh_gatts_if,
965                                         &bta_uuid, 0, svc->attr_count, false);
966                 if (future_await(gatts_future_mesh) == FUTURE_FAIL) {
967                     BT_ERR("Failed to add secondary service");
968                     return ESP_FAIL;
969                 }
970                 svc->attrs[i].handle = svc_handle;
971                 BT_DBG("Add secondary service, uuid 0x%04x, perm %d, handle %d",
972                         bta_uuid.uu.uuid16, svc->attrs[i].perm, svc_handle);
973                 break;
974             }
975             case BLE_MESH_UUID_GATT_INCLUDE_VAL: {
976                 break;
977             }
978             case BLE_MESH_UUID_GATT_CHRC_VAL: {
979                 gatts_future_mesh = future_new();
980                 struct bt_mesh_gatt_char *gatts_chrc = (struct bt_mesh_gatt_char *)svc->attrs[i].user_data;
981                 bta_uuid_to_bt_mesh_uuid(&bta_uuid, gatts_chrc->uuid);
982                 BTA_GATTS_AddCharacteristic(svc_handle, &bta_uuid, bt_mesh_perm_to_bta_perm(svc->attrs[i + 1].perm), gatts_chrc->properties, NULL, NULL);
983                 if (future_await(gatts_future_mesh) == FUTURE_FAIL) {
984                     BT_ERR("Failed to add characteristic");
985                     return ESP_FAIL;
986                 }
987                 /* All the characteristic should have two handles: the declaration handle and the value handle */
988                 svc->attrs[i].handle = char_handle - 1;
989                 svc->attrs[i + 1].handle =  char_handle;
990                 BT_DBG("Add characteristic, uuid 0x%04x, handle %d, perm %d, properties %d",
991                         BLE_MESH_UUID_16(gatts_chrc->uuid)->val, char_handle, svc->attrs[i + 1].perm, gatts_chrc->properties);
992                 break;
993             }
994             case BLE_MESH_UUID_GATT_CEP_VAL:
995             case BLE_MESH_UUID_GATT_CUD_VAL:
996             case BLE_MESH_UUID_GATT_CCC_VAL:
997             case BLE_MESH_UUID_GATT_SCC_VAL:
998             case BLE_MESH_UUID_GATT_CPF_VAL:
999             case BLE_MESH_UUID_VALID_RANGE_VAL:
1000             case BLE_MESH_UUID_HIDS_EXT_REPORT_VAL:
1001             case BLE_MESH_UUID_HIDS_REPORT_REF_VAL:
1002             case BLE_MESH_UUID_ES_CONFIGURATION_VAL:
1003             case BLE_MESH_UUID_ES_MEASUREMENT_VAL:
1004             case BLE_MESH_UUID_ES_TRIGGER_SETTING_VAL: {
1005                 gatts_future_mesh = future_new();
1006                 bta_uuid_to_bt_mesh_uuid(&bta_uuid, svc->attrs[i].uuid);
1007                 BTA_GATTS_AddCharDescriptor(svc_handle, bt_mesh_perm_to_bta_perm(svc->attrs[i].perm), &bta_uuid, NULL, NULL);
1008                 if (future_await(gatts_future_mesh) == FUTURE_FAIL) {
1009                     BT_ERR("Failed to add descriptor");
1010                     return ESP_FAIL;
1011                 }
1012                 svc->attrs[i].handle = char_handle;
1013                 BT_DBG("Add descriptor, uuid 0x%04x, perm %d, handle %d",
1014                        BLE_MESH_UUID_16(svc->attrs[i].uuid)->val, svc->attrs[i].perm, char_handle);
1015                 break;
1016             }
1017             default:
1018                 break;
1019             }
1020         }
1021     }
1022 
1023     if (svc_handle != 0) {
1024         svc_handle = 0;
1025     }
1026 
1027     gatts_register(svc);
1028     return 0;
1029 }
1030 
bt_mesh_gatts_service_deregister(struct bt_mesh_gatt_service * svc)1031 int bt_mesh_gatts_service_deregister(struct bt_mesh_gatt_service *svc)
1032 {
1033     assert(svc != NULL);
1034 
1035     gatts_deregister(svc);
1036 
1037     BTA_GATTS_DeleteService(svc->attrs[0].handle);
1038 
1039     return 0;
1040 }
1041 
bt_mesh_gatts_disconnect(struct bt_mesh_conn * conn,uint8_t reason)1042 int bt_mesh_gatts_disconnect(struct bt_mesh_conn *conn, uint8_t reason)
1043 {
1044     UNUSED(reason);
1045     uint16_t conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gatts_if, conn->handle);
1046     BTA_GATTS_Close(conn_id);
1047     return 0;
1048 }
1049 
bt_mesh_gatts_service_unregister(struct bt_mesh_gatt_service * svc)1050 int bt_mesh_gatts_service_unregister(struct bt_mesh_gatt_service *svc)
1051 {
1052     assert(svc != NULL);
1053 
1054     BTA_GATTS_DeleteService(svc->attrs[0].handle);
1055     return 0;
1056 }
1057 
bt_mesh_gatts_notify(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,const void * data,uint16_t len)1058 int bt_mesh_gatts_notify(struct bt_mesh_conn *conn,
1059                          const struct bt_mesh_gatt_attr *attr,
1060                          const void *data, uint16_t len)
1061 {
1062     uint16_t conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gatts_if, conn->handle);
1063     BTA_GATTS_HandleValueIndication(conn_id, attr->handle, len, (uint8_t *)data, false);
1064     return 0;
1065 }
1066 
bt_mesh_gatt_get_mtu(struct bt_mesh_conn * conn)1067 uint16_t bt_mesh_gatt_get_mtu(struct bt_mesh_conn *conn)
1068 {
1069     return BTA_GATT_GetLocalMTU();
1070 }
1071 
1072 /* APIs added by Espressif */
bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service * svc)1073 int bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service *svc)
1074 {
1075     if (!svc) {
1076         BT_ERR("%s, Invalid parameter", __func__);
1077         return -EINVAL;
1078     }
1079 
1080     BT_DBG("Stop service:%d", svc->attrs[0].handle);
1081 
1082     BTA_GATTS_StopService(svc->attrs[0].handle);
1083     return 0;
1084 }
1085 
bt_mesh_gatts_service_start(struct bt_mesh_gatt_service * svc)1086 int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc)
1087 {
1088     struct bt_mesh_uuid_16 *uuid_16 = NULL;
1089     struct bt_mesh_uuid *uuid = NULL;
1090 
1091     if (!svc) {
1092         BT_ERR("%s, Invalid parameter", __func__);
1093         return -EINVAL;
1094     }
1095 
1096     BT_DBG("Start service:%d", svc->attrs[0].handle);
1097 
1098     BTA_GATTS_StartService(svc->attrs[0].handle, BTA_GATT_TRANSPORT_LE);
1099 
1100     /* For EspBleMesh Android app, it does not disconnect after provisioning
1101      * is done, and hence we send GATT service change indication manually
1102      * when Mesh Proxy Service is started after provisioning.
1103      */
1104     uuid = (struct bt_mesh_uuid *)svc->attrs[0].user_data;
1105     if (uuid && uuid->type == BLE_MESH_UUID_TYPE_16) {
1106         uuid_16 = (struct bt_mesh_uuid_16 *)uuid;
1107         BT_DBG("service start, type 0x%02x, val 0x%04x", uuid_16->uuid.type, uuid_16->val);
1108         if (uuid_16->val == BLE_MESH_UUID_MESH_PROXY_VAL) {
1109             BTA_GATTS_SendServiceChangeIndication(bt_mesh_gatts_if, bt_mesh_gatts_addr);
1110         }
1111     }
1112 
1113     return 0;
1114 }
1115 
bt_mesh_gatts_set_local_device_name(const char * name)1116 int bt_mesh_gatts_set_local_device_name(const char *name)
1117 {
1118     BTM_SetLocalDeviceName((char *)name);
1119 
1120     return 0;
1121 }
1122 
1123 #endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
1124 
1125 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
1126     CONFIG_BLE_MESH_GATT_PROXY_CLIENT
bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb * cb)1127 void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb)
1128 {
1129     bt_mesh_gattc_conn_cb = cb;
1130 }
1131 
bt_mesh_gattc_conn_cb_deregister(void)1132 void bt_mesh_gattc_conn_cb_deregister(void)
1133 {
1134     bt_mesh_gattc_conn_cb = NULL;
1135 }
1136 
bt_mesh_gattc_get_free_conn_count(void)1137 uint8_t bt_mesh_gattc_get_free_conn_count(void)
1138 {
1139     uint8_t count = 0U;
1140     int i;
1141 
1142     for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1143         if (bt_mesh_gattc_info[i].conn.handle == 0xFFFF &&
1144                 bt_mesh_gattc_info[i].service_uuid == 0x0000) {
1145             ++count;
1146         }
1147     }
1148 
1149     return count;
1150 }
1151 
bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn * conn)1152 uint16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
1153 {
1154     int i;
1155 
1156     for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1157         if (conn == &bt_mesh_gattc_info[i].conn) {
1158             return bt_mesh_gattc_info[i].service_uuid;
1159         }
1160     }
1161 
1162     BT_ERR("Conn %p not found", conn);
1163     return 0;
1164 }
1165 
1166 /** For provisioner acting as a GATT client, it may follow the procedures
1167  *  listed below.
1168  *  1. Create connection with the unprovisioned device
1169  *  2. Exchange MTU size
1170  *  3. Find Mesh Prov Service in the device's service database
1171  *  4. Find Mesh Prov Data In/Out characteristic within the service
1172  *  5. Get CCC of Mesh Prov Data Out Characteristic
1173  *  6. Set the Notification bit of CCC
1174  */
1175 
bt_mesh_gattc_conn_create(const bt_mesh_addr_t * addr,uint16_t service_uuid)1176 int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
1177 {
1178     tBTA_BLE_CONN_PARAMS  conn_1m_param = {0};
1179     uint8_t zero[6] = {0};
1180     int i;
1181 
1182     if (!addr || !memcmp(addr->val, zero, BLE_MESH_ADDR_LEN) ||
1183             (addr->type > BLE_ADDR_RANDOM)) {
1184         BT_ERR("Invalid remote address");
1185         return -EINVAL;
1186     }
1187 
1188     if (service_uuid != BLE_MESH_UUID_MESH_PROV_VAL &&
1189             service_uuid != BLE_MESH_UUID_MESH_PROXY_VAL) {
1190         BT_ERR("Invalid service uuid 0x%04x", service_uuid);
1191         return -EINVAL;
1192     }
1193 
1194     /* Check if already creating connection with the device */
1195     for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1196         if (!memcmp(bt_mesh_gattc_info[i].addr.val, addr->val, BLE_MESH_ADDR_LEN)) {
1197             BT_WARN("Already create connection with %s",
1198                     bt_hex(addr->val, BLE_MESH_ADDR_LEN));
1199             return -EALREADY;
1200         }
1201     }
1202 
1203     /* Find empty element in queue to store device info */
1204     for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1205         if ((bt_mesh_gattc_info[i].conn.handle == 0xFFFF) &&
1206                 (bt_mesh_gattc_info[i].service_uuid == 0x0000)) {
1207             memcpy(bt_mesh_gattc_info[i].addr.val, addr->val, BLE_MESH_ADDR_LEN);
1208             bt_mesh_gattc_info[i].addr.type = addr->type;
1209             /* Service to be found after exchanging mtu size */
1210             bt_mesh_gattc_info[i].service_uuid = service_uuid;
1211             break;
1212         }
1213     }
1214 
1215     if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
1216         BT_WARN("gattc info is full");
1217         return -ENOMEM;
1218     }
1219 
1220     if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
1221         BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(false, 0, NULL, NULL, NULL));
1222         bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
1223     }
1224 
1225     BT_DBG("Create conn with %s", bt_hex(addr->val, BLE_MESH_ADDR_LEN));
1226 
1227     /* Min_interval: 15ms
1228      * Max_interval: 15ms
1229      * Slave_latency: 0x0
1230      * Supervision_timeout: 1s
1231      */
1232     conn_1m_param.interval_min = 0x18;
1233     conn_1m_param.interval_max = 0x18;
1234     conn_1m_param.latency = 0;
1235     conn_1m_param.supervision_timeout = 0x64;
1236 
1237     BTA_GATTC_Enh_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
1238                    bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE,
1239                    BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL);
1240 
1241     return 0;
1242 }
1243 
bt_mesh_gattc_exchange_mtu(uint8_t index)1244 void bt_mesh_gattc_exchange_mtu(uint8_t index)
1245 {
1246     /** Set local MTU and exchange with GATT server.
1247      *  ATT_MTU >= 69 for Mesh GATT Prov Service
1248      *  ATT_NTU >= 33 for Mesh GATT Proxy Service
1249     */
1250     uint16_t conn_id = 0U;
1251 
1252     conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[index].conn.handle);
1253 
1254     BTA_GATTC_ConfigureMTU(conn_id);
1255 }
1256 
bt_mesh_gattc_get_mtu_info(struct bt_mesh_conn * conn)1257 uint16_t bt_mesh_gattc_get_mtu_info(struct bt_mesh_conn *conn)
1258 {
1259     int i;
1260 
1261     for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1262         if (conn == &bt_mesh_gattc_info[i].conn) {
1263             return bt_mesh_gattc_info[i].mtu;
1264         }
1265     }
1266 
1267     return 0;
1268 }
1269 
bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,const void * data,uint16_t len)1270 int bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn *conn,
1271                                const struct bt_mesh_gatt_attr *attr,
1272                                const void *data, uint16_t len)
1273 {
1274     uint16_t conn_id = 0U;
1275     int i;
1276 
1277     for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1278         if (conn == &bt_mesh_gattc_info[i].conn) {
1279             conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
1280             BTA_GATTC_WriteCharValue(conn_id, bt_mesh_gattc_info[i].data_in_handle,
1281                                      BTA_GATTC_TYPE_WRITE_NO_RSP, len,
1282                                      (uint8_t *)data, BTA_GATT_AUTH_REQ_NONE);
1283             return 0;
1284         }
1285     }
1286 
1287     BT_ERR("Conn %p not found", conn);
1288     return -EEXIST;
1289 }
1290 
bt_mesh_gattc_disconnect(struct bt_mesh_conn * conn)1291 void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn)
1292 {
1293     /** Disconnect
1294      *  Clear proper proxy server information
1295      *  Clear proper prov_link information
1296      *  Clear proper bt_mesh_gattc_info information
1297      *  Here in adapter, we just clear proper bt_mesh_gattc_info, and
1298      *  when proxy_disconnected callback comes, the proxy server
1299      *  information and prov_link information should be cleared.
1300      */
1301     uint16_t conn_id = 0U;
1302     int i;
1303 
1304     for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1305         if (conn == &bt_mesh_gattc_info[i].conn) {
1306             conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_if, bt_mesh_gattc_info[i].conn.handle);
1307             BTA_GATTC_Close(conn_id);
1308             return;
1309         }
1310     }
1311 
1312     BT_ERR("Conn %p not found", conn);
1313     return;
1314 }
1315 
1316 /** Mesh Provisioning Service:  0x1827
1317  *  Mesh Provisioning Data In:  0x2ADB
1318  *  Mesh Provisioning Data Out: 0x2ADC
1319  *  Mesh Proxy Service:  0x1828
1320  *  Mesh Proxy Data In:  0x2ADD
1321  *  Mesh PROXY Data Out: 0x2ADE
1322  */
bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)1323 static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
1324 {
1325     struct bt_mesh_conn *conn = NULL;
1326     uint16_t handle = 0U;
1327     ssize_t len = 0;
1328     int i = 0;
1329 
1330     switch (event) {
1331     case BTA_GATTC_REG_EVT:
1332         if (p_data->reg_oper.status == BTA_GATT_OK) {
1333             uint8_t uuid[16] = { [0 ... 15] = BLE_MESH_GATTC_APP_UUID_BYTE };
1334 
1335             BT_DBG("BTA_GATTC_REG_EVT");
1336 
1337             if (p_data->reg_oper.app_uuid.len == LEN_UUID_128 &&
1338                     !memcmp(p_data->reg_oper.app_uuid.uu.uuid128, uuid, 16)) {
1339                 bt_mesh_gattc_if = p_data->reg_oper.client_if;
1340                 BT_DBG("bt_mesh_gattc_if is %d", bt_mesh_gattc_if);
1341             }
1342         }
1343         break;
1344     case BTA_GATTC_CFG_MTU_EVT: {
1345         if (p_data->cfg_mtu.status == BTA_GATT_OK) {
1346             BT_DBG("BTA_GATTC_CFG_MTU_EVT, cfg_mtu is %d", p_data->cfg_mtu.mtu);
1347 
1348             handle = BLE_MESH_GATT_GET_CONN_ID(p_data->cfg_mtu.conn_id);
1349 
1350             for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1351                 if (bt_mesh_gattc_info[i].conn.handle == handle) {
1352                     bt_mesh_gattc_info[i].mtu = p_data->cfg_mtu.mtu;
1353 
1354                     /* Search Mesh Provisioning Service or Mesh Proxy Service */
1355                     tBT_UUID service_uuid = {
1356                         .len = sizeof(bt_mesh_gattc_info[i].service_uuid),
1357                         .uu.uuid16 = bt_mesh_gattc_info[i].service_uuid,
1358                     };
1359                     BTA_GATTC_ServiceSearchRequest(p_data->cfg_mtu.conn_id, &service_uuid);
1360                     break;
1361                 }
1362             }
1363         }
1364         break;
1365     }
1366     case BTA_GATTC_SEARCH_RES_EVT: {
1367         BT_DBG("BTA_GATTC_SEARCH_RES_EVT");
1368 
1369         handle = BLE_MESH_GATT_GET_CONN_ID(p_data->srvc_res.conn_id);
1370 
1371         for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1372             if (bt_mesh_gattc_info[i].conn.handle == handle) {
1373                 if (p_data->srvc_res.service_uuid.uuid.len == 2 &&
1374                         p_data->srvc_res.service_uuid.uuid.uu.uuid16 == bt_mesh_gattc_info[i].service_uuid) {
1375                     bt_mesh_gattc_info[i].start_handle = p_data->srvc_res.start_handle;
1376                     bt_mesh_gattc_info[i].end_handle = p_data->srvc_res.end_handle;
1377                 }
1378                 break;
1379             }
1380         }
1381         break;
1382     }
1383     case BTA_GATTC_SEARCH_CMPL_EVT: {
1384         if (p_data->search_cmpl.status == BTA_GATT_OK) {
1385             BT_DBG("BTA_GATTC_SEARCH_CMPL_EVT");
1386 
1387             handle = BLE_MESH_GATT_GET_CONN_ID(p_data->search_cmpl.conn_id);
1388 
1389             for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1390                 if (bt_mesh_gattc_info[i].conn.handle == handle) {
1391                     conn = &bt_mesh_gattc_info[i].conn;
1392                     break;
1393                 }
1394             }
1395 
1396             if (conn == NULL) {
1397                 BT_ERR("Conn handle 0x%04x not found", handle);
1398                 return;
1399             }
1400 
1401             if (bt_mesh_gattc_info[i].start_handle == 0x00 ||
1402                     bt_mesh_gattc_info[i].end_handle == 0x00 ||
1403                     (bt_mesh_gattc_info[i].start_handle > bt_mesh_gattc_info[i].end_handle)) {
1404                 bt_mesh_gattc_disconnect(conn);
1405                 return;
1406             }
1407 
1408             uint16_t notify_en = BLE_MESH_GATT_CCC_NOTIFY;
1409             btgatt_db_element_t *result = NULL;
1410             tBT_UUID char_uuid = {0};
1411             tBTA_GATT_STATUS status = 0U;
1412             tBTA_GATT_UNFMT write = {0};
1413             uint16_t count = 0U;
1414             uint16_t num = 0;
1415 
1416             /* Get the characteristic num within Mesh Provisioning/Proxy Service */
1417             BTA_GATTC_GetDBSizeByType(p_data->search_cmpl.conn_id, BTGATT_DB_CHARACTERISTIC,
1418                                       bt_mesh_gattc_info[i].start_handle, bt_mesh_gattc_info[i].end_handle,
1419                                       BTA_GATTC_INVALID_HANDLE, &count);
1420             if (count != 2) {
1421                 bt_mesh_gattc_disconnect(conn);
1422                 return;
1423             }
1424 
1425             /* Get Mesh Provisioning/Proxy Data In/Out Characteristic */
1426             for (int j = 0; j != 2; j++) {
1427                 /** First:  find Mesh Provisioning/Proxy Data In Characteristic
1428                  *  Second: find Mesh Provisioning/Proxy Data Out Characteristic
1429                  */
1430                 char_uuid.len = 2;
1431                 if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
1432                     char_uuid.uu.uuid16 = BLE_MESH_UUID_MESH_PROV_DATA_IN_VAL + j;
1433                 } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) {
1434                     char_uuid.uu.uuid16 = BLE_MESH_UUID_MESH_PROXY_DATA_IN_VAL + j;
1435                 }
1436 
1437                 BTA_GATTC_GetCharByUUID(p_data->search_cmpl.conn_id, bt_mesh_gattc_info[i].start_handle,
1438                                         bt_mesh_gattc_info[i].end_handle, char_uuid, &result, &num);
1439 
1440                 if (!result) {
1441                     bt_mesh_gattc_disconnect(conn);
1442                     return;
1443                 }
1444 
1445                 if (num != 1) {
1446                     bt_mesh_free(result);
1447                     bt_mesh_gattc_disconnect(conn);
1448                     return;
1449                 }
1450 
1451                 if (!j) {
1452                     if (!(result[0].properties & BLE_MESH_GATT_CHRC_WRITE_WITHOUT_RESP)) {
1453                         bt_mesh_free(result);
1454                         bt_mesh_gattc_disconnect(conn);
1455                         return;
1456                     }
1457                     bt_mesh_gattc_info[i].data_in_handle = result[0].attribute_handle;
1458                 } else {
1459                     if (!(result[0].properties & BLE_MESH_GATT_CHRC_NOTIFY)) {
1460                         bt_mesh_free(result);
1461                         bt_mesh_gattc_disconnect(conn);
1462                         return;
1463                     }
1464                     bt_mesh_gattc_info[i].data_out_handle = result[0].attribute_handle;
1465                 }
1466 
1467                 bt_mesh_free(result);
1468                 result = NULL;
1469             }
1470 
1471             /* Register Notification fot Mesh Provisioning/Proxy Data Out Characteristic */
1472             status = BTA_GATTC_RegisterForNotifications(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
1473                      bt_mesh_gattc_info[i].data_out_handle);
1474             if (status != BTA_GATT_OK) {
1475                 bt_mesh_gattc_disconnect(conn);
1476                 return;
1477             }
1478 
1479             /** After notification is registered, get descriptor number of the
1480              *  Mesh Provisioning/Proxy Data Out Characteristic
1481              */
1482             BTA_GATTC_GetDBSizeByType(p_data->search_cmpl.conn_id, BTGATT_DB_DESCRIPTOR,
1483                                       bt_mesh_gattc_info[i].start_handle, bt_mesh_gattc_info[i].end_handle,
1484                                       bt_mesh_gattc_info[i].data_out_handle, &num);
1485             if (!num) {
1486                 bt_mesh_gattc_disconnect(conn);
1487                 return;
1488             }
1489 
1490             /* Get CCC of Mesh Provisioning/Proxy Data Out Characteristic */
1491             char_uuid.len = 2;
1492             char_uuid.uu.uuid16 = BLE_MESH_UUID_GATT_CCC_VAL;
1493             BTA_GATTC_GetDescrByCharHandle(p_data->search_cmpl.conn_id, bt_mesh_gattc_info[i].data_out_handle,
1494                                            char_uuid, &result, &num);
1495             if (!result) {
1496                 bt_mesh_gattc_disconnect(conn);
1497                 return;
1498             }
1499 
1500             if (num != 1) {
1501                 bt_mesh_free(result);
1502                 bt_mesh_gattc_disconnect(conn);
1503                 return;
1504             }
1505 
1506             bt_mesh_gattc_info[i].ccc_handle = result[0].attribute_handle;
1507 
1508             /** Enable Notification of Mesh Provisioning/Proxy Data Out
1509              *  Characteristic Descriptor.
1510              */
1511             write.len = sizeof(notify_en);
1512             write.p_value = (uint8_t *)&notify_en;
1513             BTA_GATTC_WriteCharDescr(p_data->search_cmpl.conn_id, result[0].attribute_handle,
1514                                      BTA_GATTC_TYPE_WRITE, &write, BTA_GATT_AUTH_REQ_NONE);
1515 
1516             bt_mesh_free(result);
1517             result = NULL;
1518         }
1519         break;
1520     }
1521     case BTA_GATTC_READ_DESCR_EVT:
1522         break;
1523     case BTA_GATTC_WRITE_DESCR_EVT: {
1524         if (p_data->write.status == BTA_GATT_OK) {
1525             BT_DBG("BTA_GATTC_WRITE_DESCR_EVT");
1526 
1527             handle = BLE_MESH_GATT_GET_CONN_ID(p_data->write.conn_id);
1528 
1529             for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1530                 if (bt_mesh_gattc_info[i].conn.handle == handle) {
1531                     conn = &bt_mesh_gattc_info[i].conn;
1532                     break;
1533                 }
1534             }
1535 
1536             if (conn == NULL) {
1537                 BT_ERR("Conn handle 0x%04x not found", handle);
1538                 return;
1539             }
1540 
1541             if (bt_mesh_gattc_info[i].ccc_handle != p_data->write.handle) {
1542                 BT_WARN("gattc ccc_handle not matched");
1543                 bt_mesh_gattc_disconnect(conn);
1544                 return;
1545             }
1546 
1547             if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
1548                 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_write_descr != NULL) {
1549                     len = bt_mesh_gattc_conn_cb->prov_write_descr(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn);
1550                     if (len < 0) {
1551                         BT_ERR("prov_write_descr failed");
1552                         bt_mesh_gattc_disconnect(conn);
1553                         return;
1554                     }
1555                     bt_mesh_gattc_info[i].wr_desc_done = true;
1556                 }
1557             } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) {
1558                 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_write_descr != NULL) {
1559                     len = bt_mesh_gattc_conn_cb->proxy_write_descr(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn);
1560                     if (len < 0) {
1561                         BT_ERR("proxy_write_descr failed");
1562                         bt_mesh_gattc_disconnect(conn);
1563                         return;
1564                     }
1565                     bt_mesh_gattc_info[i].wr_desc_done = true;
1566                 }
1567             }
1568         }
1569         break;
1570     }
1571     case BTA_GATTC_NOTIF_EVT: {
1572         BT_DBG("BTA_GATTC_NOTIF_EVT");
1573 
1574         handle = BLE_MESH_GATT_GET_CONN_ID(p_data->notify.conn_id);
1575 
1576         for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1577             if (bt_mesh_gattc_info[i].conn.handle == handle) {
1578                 if (bt_mesh_gattc_info[i].wr_desc_done == false) {
1579                     BT_DBG("Receive notification before finishing to write ccc");
1580                     return;
1581                 }
1582 
1583                 conn = &bt_mesh_gattc_info[i].conn;
1584                 break;
1585             }
1586         }
1587 
1588         if (conn == NULL) {
1589             BT_ERR("Conn handle 0x%04x not found", handle);
1590             return;
1591         }
1592 
1593         if (memcmp(bt_mesh_gattc_info[i].addr.val, p_data->notify.bda, BLE_MESH_ADDR_LEN) ||
1594                 bt_mesh_gattc_info[i].data_out_handle != p_data->notify.handle ||
1595                 p_data->notify.is_notify == false) {
1596             BT_ERR("Notification error");
1597             bt_mesh_gattc_disconnect(conn);
1598             return;
1599         }
1600 
1601         if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
1602             if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_notify != NULL) {
1603                 len = bt_mesh_gattc_conn_cb->prov_notify(&bt_mesh_gattc_info[i].conn,
1604                         p_data->notify.value, p_data->notify.len);
1605                 if (len < 0) {
1606                     BT_ERR("prov_notify failed");
1607                     bt_mesh_gattc_disconnect(conn);
1608                     return;
1609                 }
1610             }
1611         } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) {
1612             if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL) {
1613                 len = bt_mesh_gattc_conn_cb->proxy_notify(&bt_mesh_gattc_info[i].conn,
1614                         p_data->notify.value, p_data->notify.len);
1615                 if (len < 0) {
1616                     BT_ERR("proxy_notify failed");
1617                     bt_mesh_gattc_disconnect(conn);
1618                     return;
1619                 }
1620             }
1621         }
1622         break;
1623     }
1624     case BTA_GATTC_READ_CHAR_EVT:
1625         break;
1626     case BTA_GATTC_WRITE_CHAR_EVT:
1627         break;
1628     case BTA_GATTC_PREP_WRITE_EVT:
1629         break;
1630     case BTA_GATTC_EXEC_EVT:
1631         break;
1632     case BTA_GATTC_OPEN_EVT:
1633         BT_DBG("BTA_GATTC_OPEN_EVT");
1634         /* After current connection is established, Provisioner can
1635          * use BTM_BleScan() to re-enable scan.
1636          */
1637         if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
1638             tBTM_STATUS status = BTM_BleScan(true, 0, bt_mesh_scan_results_cb, NULL, NULL);
1639             if (status != BTM_SUCCESS && status != BTM_CMD_STARTED) {
1640                 BT_ERR("Invalid scan status %d", status);
1641                 break;
1642             }
1643             bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
1644         }
1645         break;
1646     case BTA_GATTC_CLOSE_EVT:
1647         bta_gattc_clcb_dealloc_by_conn_id(p_data->close.conn_id);
1648         BT_DBG("BTA_GATTC_CLOSE_EVT");
1649         break;
1650     case BTA_GATTC_CONNECT_EVT: {
1651         BT_DBG("BTA_GATTC_CONNECT_EVT");
1652 
1653         if (bt_mesh_gattc_if != p_data->connect.client_if) {
1654             BT_ERR("gattc_if & connect_if mismatch");
1655             return;
1656         }
1657 
1658         if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->connected != NULL) {
1659             for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1660                 if (!memcmp(bt_mesh_gattc_info[i].addr.val, p_data->connect.remote_bda, BLE_MESH_ADDR_LEN)) {
1661                     bt_mesh_gattc_info[i].conn.handle = BLE_MESH_GATT_GET_CONN_ID(p_data->connect.conn_id);
1662                     (bt_mesh_gattc_conn_cb->connected)(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, i);
1663                     break;
1664                 }
1665             }
1666         }
1667         break;
1668     }
1669     case BTA_GATTC_DISCONNECT_EVT: {
1670         BT_DBG("BTA_GATTC_DISCONNECT_EVT");
1671 
1672         if (bt_mesh_gattc_if != p_data->disconnect.client_if) {
1673             BT_ERR("gattc_if & disconnect_if mismatch");
1674             return;
1675         }
1676 
1677         handle = BLE_MESH_GATT_GET_CONN_ID(p_data->disconnect.conn_id);
1678 
1679         if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->disconnected != NULL) {
1680             for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1681                 if (!memcmp(bt_mesh_gattc_info[i].addr.val, p_data->disconnect.remote_bda, BLE_MESH_ADDR_LEN)) {
1682                     if (bt_mesh_gattc_info[i].conn.handle == handle) {
1683                         (bt_mesh_gattc_conn_cb->disconnected)(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, p_data->disconnect.reason);
1684                         if (!bt_mesh_gattc_info[i].wr_desc_done) {
1685                             /* Add this in case connection is established, connected event comes, but
1686                              * connection is terminated before server->filter_type is set to PROV.
1687                              */
1688 #if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
1689                             if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
1690                                 bt_mesh_provisioner_clear_link_info(bt_mesh_gattc_info[i].addr.val);
1691                             }
1692 #endif
1693                         }
1694                     } else {
1695                         /* Add this in case connection is failed to be established, and here we
1696                          * need to clear some provision link info, like connecting flag, device
1697                          * uuid, address info, etc.
1698                          */
1699 #if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
1700                         if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
1701                             bt_mesh_provisioner_clear_link_info(bt_mesh_gattc_info[i].addr.val);
1702                         }
1703 #endif
1704                     }
1705 #if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
1706                     if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
1707                         /* Decrease provisioner pbg_count */
1708                         bt_mesh_provisioner_pbg_count_dec();
1709                     }
1710 #endif
1711                     /* Reset corresponding gattc info */
1712                     memset(&bt_mesh_gattc_info[i], 0, sizeof(bt_mesh_gattc_info[i]));
1713                     bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
1714                     bt_mesh_gattc_info[i].mtu = GATT_DEF_BLE_MTU_SIZE;
1715                     bt_mesh_gattc_info[i].wr_desc_done = false;
1716                     break;
1717                 }
1718             }
1719         }
1720         break;
1721     }
1722     case BTA_GATTC_CONGEST_EVT:
1723         break;
1724     case BTA_GATTC_SRVC_CHG_EVT:
1725         break;
1726     default:
1727         break;
1728     }
1729 }
1730 #endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
1731 
bt_mesh_conn_ref(struct bt_mesh_conn * conn)1732 struct bt_mesh_conn *bt_mesh_conn_ref(struct bt_mesh_conn *conn)
1733 {
1734     bt_mesh_atomic_inc(&conn->ref);
1735 
1736     BT_DBG("handle %u ref %u", conn->handle, bt_mesh_atomic_get(&conn->ref));
1737 
1738     return conn;
1739 }
1740 
bt_mesh_conn_unref(struct bt_mesh_conn * conn)1741 void bt_mesh_conn_unref(struct bt_mesh_conn *conn)
1742 {
1743     bt_mesh_atomic_dec(&conn->ref);
1744 
1745     BT_DBG("handle %u ref %u", conn->handle, bt_mesh_atomic_get(&conn->ref));
1746 }
1747 
bt_mesh_gatt_init(void)1748 void bt_mesh_gatt_init(void)
1749 {
1750     BTA_GATT_SetLocalMTU(GATT_DEF_BLE_MTU_SIZE);
1751 
1752 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
1753     CONFIG_BLE_MESH_GATT_PROXY_SERVER
1754     tBT_UUID gatts_app_uuid = {LEN_UUID_128, {0}};
1755     memset(&gatts_app_uuid.uu.uuid128, BLE_MESH_GATTS_APP_UUID_BYTE, LEN_UUID_128);
1756 
1757     gatts_future_mesh = future_new();
1758     if (!gatts_future_mesh) {
1759         BT_ERR("Mesh gatts sync lock alloc failed");
1760         return;
1761     }
1762 
1763     BTA_GATTS_AppRegister(&gatts_app_uuid, bt_mesh_bta_gatts_cb);
1764 
1765     if (future_await(gatts_future_mesh) == FUTURE_FAIL) {
1766         BT_ERR("Mesh gatts app register failed");
1767         return;
1768     }
1769 #endif
1770 
1771 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
1772     CONFIG_BLE_MESH_GATT_PROXY_CLIENT
1773     tBT_UUID gattc_app_uuid = {LEN_UUID_128, {0}};
1774     for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1775         bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
1776         bt_mesh_gattc_info[i].mtu = GATT_DEF_BLE_MTU_SIZE; /* Default MTU_SIZE 23 */
1777         bt_mesh_gattc_info[i].wr_desc_done = false;
1778     }
1779     memset(&gattc_app_uuid.uu.uuid128, BLE_MESH_GATTC_APP_UUID_BYTE, LEN_UUID_128);
1780     BTA_GATTC_AppRegister(&gattc_app_uuid, bt_mesh_bta_gattc_cb);
1781 #endif
1782 }
1783 
1784 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_gatt_deinit(void)1785 void bt_mesh_gatt_deinit(void)
1786 {
1787 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
1788     CONFIG_BLE_MESH_GATT_PROXY_SERVER
1789     BTA_GATTS_AppDeregister(bt_mesh_gatts_if);
1790     memset(bt_mesh_gatts_addr, 0, BLE_MESH_ADDR_LEN);
1791     bt_mesh_gatts_if = 0U;
1792     svc_handle = 0U;
1793     char_handle = 0U;
1794 #endif
1795 
1796 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
1797     CONFIG_BLE_MESH_GATT_PROXY_CLIENT
1798     BTA_GATTC_AppDeregister(bt_mesh_gattc_if);
1799     bt_mesh_gattc_if = 0U;
1800     for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1801         bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
1802         memset(&bt_mesh_gattc_info[i].addr, 0, sizeof(bt_mesh_addr_t));
1803         bt_mesh_gattc_info[i].service_uuid = 0U;
1804         bt_mesh_gattc_info[i].mtu = GATT_DEF_BLE_MTU_SIZE; /* Default MTU_SIZE 23 */
1805         bt_mesh_gattc_info[i].wr_desc_done = false;
1806         bt_mesh_gattc_info[i].start_handle = 0U;
1807         bt_mesh_gattc_info[i].end_handle = 0U;
1808         bt_mesh_gattc_info[i].data_in_handle = 0U;
1809         bt_mesh_gattc_info[i].data_out_handle = 0U;
1810         bt_mesh_gattc_info[i].ccc_handle = 0U;
1811     }
1812 #endif
1813 }
1814 #endif /* CONFIG_BLE_MESH_DEINIT */
1815 
bt_mesh_adapt_init(void)1816 void bt_mesh_adapt_init(void)
1817 {
1818     BT_DBG("%s", __func__);
1819 
1820     /* initialization of P-256 parameters */
1821     p_256_init_curve(KEY_LENGTH_DWORDS_P256);
1822 
1823     /* Set "bt_mesh_dev.flags" to 0 (only the "BLE_MESH_DEV_HAS_PUB_KEY"
1824      * flag is used) here, because we need to make sure each time after
1825      * the private key is initialized, a corresponding public key must
1826      * be generated.
1827      */
1828     bt_mesh_atomic_set(bt_mesh_dev.flags, 0);
1829     bt_mesh_rand(bt_mesh_private_key, sizeof(bt_mesh_private_key));
1830 }
1831 
bt_mesh_set_private_key(const uint8_t pri_key[32])1832 void bt_mesh_set_private_key(const uint8_t pri_key[32])
1833 {
1834     memcpy(bt_mesh_private_key, pri_key, 32);
1835 }
1836 
bt_mesh_pub_key_get(void)1837 const uint8_t *bt_mesh_pub_key_get(void)
1838 {
1839     BT_OCTET32 private_key = {0};
1840     Point public_key = {0};
1841 
1842     if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_HAS_PUB_KEY)) {
1843         return bt_mesh_public_key;
1844     }
1845 
1846     /* BLE Mesh BQB test case MESH/NODE/PROV/UPD/BV-12-C requires
1847      * different public key for each provisioning procedure.
1848      * Note: if enabled, when Provisioner provision multiple devices
1849      * at the same time, this may cause invalid confirmation value.
1850      *
1851      * Use the following code for generating different private key
1852      * for each provisioning procedure.
1853      *
1854      * if (bt_mesh_rand(bt_mesh_private_key, BT_OCTET32_LEN)) {
1855      *    BT_ERR("%s, Unable to generate bt_mesh_private_key", __func__);
1856      *    return NULL;
1857      * }
1858      */
1859 
1860     memcpy(private_key, bt_mesh_private_key, BT_OCTET32_LEN);
1861     ECC_PointMult(&public_key, &(curve_p256.G), (DWORD *)private_key, KEY_LENGTH_DWORDS_P256);
1862 
1863     memcpy(bt_mesh_public_key, public_key.x, BT_OCTET32_LEN);
1864     memcpy(bt_mesh_public_key + BT_OCTET32_LEN, public_key.y, BT_OCTET32_LEN);
1865 
1866     bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_HAS_PUB_KEY);
1867 
1868     BT_DBG("Public Key %s", bt_hex(bt_mesh_public_key, sizeof(bt_mesh_public_key)));
1869 
1870     return bt_mesh_public_key;
1871 }
1872 
bt_mesh_check_public_key(const uint8_t key[64])1873 bool bt_mesh_check_public_key(const uint8_t key[64])
1874 {
1875     struct p256_pub_key {
1876         uint8_t x[32];
1877         uint8_t y[32];
1878     } check = {0};
1879 
1880     sys_memcpy_swap(check.x, key, 32);
1881     sys_memcpy_swap(check.y, key + 32, 32);
1882 
1883     return ECC_CheckPointIsInElliCur_P256((Point *)&check);
1884 }
1885 
bt_mesh_dh_key_gen(const uint8_t remote_pk[64],bt_mesh_dh_key_cb_t cb,const uint8_t idx)1886 int bt_mesh_dh_key_gen(const uint8_t remote_pk[64], bt_mesh_dh_key_cb_t cb, const uint8_t idx)
1887 {
1888     BT_OCTET32 private_key = {0};
1889     Point peer_pub_key = {0};
1890     Point new_pub_key = {0};
1891 
1892     BT_DBG("private key = %s", bt_hex(bt_mesh_private_key, BT_OCTET32_LEN));
1893 
1894     memcpy(private_key, bt_mesh_private_key, BT_OCTET32_LEN);
1895     memcpy(peer_pub_key.x, remote_pk, BT_OCTET32_LEN);
1896     memcpy(peer_pub_key.y, &remote_pk[BT_OCTET32_LEN], BT_OCTET32_LEN);
1897 
1898     BT_DBG("remote public key x = %s", bt_hex(peer_pub_key.x, BT_OCTET32_LEN));
1899     BT_DBG("remote public key y = %s", bt_hex(peer_pub_key.y, BT_OCTET32_LEN));
1900 
1901     ECC_PointMult(&new_pub_key, &peer_pub_key, (DWORD *)private_key, KEY_LENGTH_DWORDS_P256);
1902 
1903     BT_DBG("new public key x = %s", bt_hex(new_pub_key.x, 32));
1904     BT_DBG("new public key y = %s", bt_hex(new_pub_key.y, 32));
1905 
1906     if (cb != NULL) {
1907         cb((const uint8_t *)new_pub_key.x, idx);
1908     }
1909 
1910     return 0;
1911 }
1912 
bt_mesh_encrypt_le(const uint8_t key[16],const uint8_t plaintext[16],uint8_t enc_data[16])1913 int bt_mesh_encrypt_le(const uint8_t key[16], const uint8_t plaintext[16],
1914                        uint8_t enc_data[16])
1915 {
1916     uint8_t tmp[16] = {0};
1917 
1918     BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16));
1919 
1920 #if CONFIG_MBEDTLS_HARDWARE_AES
1921     mbedtls_aes_context ctx = {0};
1922 
1923     mbedtls_aes_init(&ctx);
1924 
1925     sys_memcpy_swap(tmp, key, 16);
1926 
1927     if (mbedtls_aes_setkey_enc(&ctx, tmp, 128) != 0) {
1928         mbedtls_aes_free(&ctx);
1929         return -EINVAL;
1930     }
1931 
1932     sys_memcpy_swap(tmp, plaintext, 16);
1933 
1934     if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT,
1935                               tmp, enc_data) != 0) {
1936         mbedtls_aes_free(&ctx);
1937         return -EINVAL;
1938     }
1939 
1940     mbedtls_aes_free(&ctx);
1941 #else /* CONFIG_MBEDTLS_HARDWARE_AES */
1942     struct tc_aes_key_sched_struct s = {0};
1943 
1944     sys_memcpy_swap(tmp, key, 16);
1945 
1946     if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) {
1947         return -EINVAL;
1948     }
1949 
1950     sys_memcpy_swap(tmp, plaintext, 16);
1951 
1952     if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) {
1953         return -EINVAL;
1954     }
1955 #endif /* CONFIG_MBEDTLS_HARDWARE_AES */
1956 
1957     sys_mem_swap(enc_data, 16);
1958 
1959     BT_DBG("enc_data %s", bt_hex(enc_data, 16));
1960 
1961     return 0;
1962 }
1963 
bt_mesh_encrypt_be(const uint8_t key[16],const uint8_t plaintext[16],uint8_t enc_data[16])1964 int bt_mesh_encrypt_be(const uint8_t key[16], const uint8_t plaintext[16],
1965                        uint8_t enc_data[16])
1966 {
1967     BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16));
1968 
1969 #if CONFIG_MBEDTLS_HARDWARE_AES
1970     mbedtls_aes_context ctx = {0};
1971 
1972     mbedtls_aes_init(&ctx);
1973 
1974     if (mbedtls_aes_setkey_enc(&ctx, key, 128) != 0) {
1975         mbedtls_aes_free(&ctx);
1976         return -EINVAL;
1977     }
1978 
1979     if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT,
1980                               plaintext, enc_data) != 0) {
1981         mbedtls_aes_free(&ctx);
1982         return -EINVAL;
1983     }
1984 
1985     mbedtls_aes_free(&ctx);
1986 #else /* CONFIG_MBEDTLS_HARDWARE_AES */
1987     struct tc_aes_key_sched_struct s = {0};
1988 
1989     if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) {
1990         return -EINVAL;
1991     }
1992 
1993     if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) {
1994         return -EINVAL;
1995     }
1996 #endif /* CONFIG_MBEDTLS_HARDWARE_AES */
1997 
1998     BT_DBG("enc_data %s", bt_hex(enc_data, 16));
1999 
2000     return 0;
2001 }
2002 
2003 #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN)
bt_mesh_update_exceptional_list(uint8_t sub_code,uint32_t type,void * info)2004 int bt_mesh_update_exceptional_list(uint8_t sub_code, uint32_t type, void *info)
2005 {
2006     BD_ADDR value = {0};
2007 
2008     if ((sub_code > BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN) ||
2009         (sub_code < BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
2010          type > BLE_MESH_EXCEP_LIST_TYPE_MESH_PROXY_ADV) ||
2011         (sub_code == BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
2012          !(type & BLE_MESH_EXCEP_LIST_CLEAN_ALL_LIST))) {
2013         BT_ERR("%s, Invalid parameter", __func__);
2014         return -EINVAL;
2015     }
2016 
2017     if (type == BLE_MESH_EXCEP_LIST_TYPE_MESH_LINK_ID) {
2018         if (!info) {
2019             BT_ERR("Invalid Provisioning Link ID");
2020             return -EINVAL;
2021         }
2022 
2023         /* When removing an unused link (i.e., Link ID is 0), and since
2024          * Controller has never added this Link ID, it will cause error
2025          * log been wrongly reported.
2026          * Therefore, add this check here to avoid such occurrences.
2027          */
2028         if (*(uint32_t*)info == 0) {
2029             return 0;
2030         }
2031 
2032         sys_memcpy_swap(value, info, sizeof(uint32_t));
2033     }
2034 
2035     BT_DBG("%s exceptional list, type 0x%08x", sub_code ? "Remove" : "Add", type);
2036 
2037     /* The parameter "device_info" can't be NULL in the API */
2038     BLE_MESH_BTM_CHECK_STATUS(BTM_UpdateBleDuplicateExceptionalList(sub_code, type, value, NULL));
2039 
2040     return 0;
2041 }
2042 #endif
2043