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(¶m.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 *)¬ify_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