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 <errno.h>
10
11 #include "btc/btc_task.h"
12 #include "osi/alarm.h"
13
14 #include "mbedtls/aes.h"
15 #include "mbedtls/ecp.h"
16
17 #include "host/ble_hs.h"
18 #include "host/ble_uuid.h"
19 #include "host/ble_att.h"
20 #include "host/ble_gatt.h"
21 #include "services/gap/ble_svc_gap.h"
22 #include "services/gatt/ble_svc_gatt.h"
23
24 #include <tinycrypt/aes.h>
25 #include <tinycrypt/constants.h>
26
27 #include "mesh_hci.h"
28 #include "mesh_common.h"
29 #include "provisioner_prov.h"
30
31 /** @def BT_UUID_MESH_PROV
32 * @brief Mesh Provisioning Service
33 */
34 #define BT_UUID_MESH_PROV_VAL 0x1827
35 /** @def BT_UUID_MESH_PROXY
36 * @brief Mesh Proxy Service
37 */
38 #define BT_UUID_MESH_PROXY_VAL 0x1828
39 /** @def BT_UUID_GATT_CCC
40 * @brief GATT Client Characteristic Configuration
41 */
42 #define BT_UUID_GATT_CCC_VAL 0x2902
43 /** @def BT_UUID_MESH_PROV_DATA_IN
44 * @brief Mesh Provisioning Data In
45 */
46 #define BT_UUID_MESH_PROV_DATA_IN_VAL 0x2adb
47 /** @def BT_UUID_MESH_PROV_DATA_OUT
48 * @brief Mesh Provisioning Data Out
49 */
50 #define BT_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc
51 /** @def BT_UUID_MESH_PROXY_DATA_IN
52 * @brief Mesh Proxy Data In
53 */
54 #define BT_UUID_MESH_PROXY_DATA_IN_VAL 0x2add
55 /** @def BT_UUID_MESH_PROXY_DATA_OUT
56 * @brief Mesh Proxy Data Out
57 */
58 #define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade
59
60 #define BLE_MESH_GATT_GET_CONN_ID(conn_id) ((uint16_t)(conn_id))
61 #define BLE_MESH_GATT_CREATE_CONN_ID(conn_id) ((uint16_t)(conn_id))
62
63 static uint16_t proxy_svc_start_handle, prov_svc_start_handle;
64 struct bt_mesh_dev bt_mesh_dev;
65
66 /* P-256 Variables */
67 static uint8_t bt_mesh_public_key[64];
68 static uint8_t bt_mesh_private_key[32];
69
70 /* Scan related functions */
71 static bt_mesh_scan_cb_t *bt_mesh_scan_dev_found_cb;
72
73 #if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE
74 /* the gatt database list to save the attribute table */
75 static sys_slist_t bt_mesh_gatts_db;
76
77 /* Static Variables */
78 static struct bt_mesh_conn bt_mesh_gatts_conn[BLE_MESH_MAX_CONN];
79 static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb;
80
81 static uint8_t bt_mesh_gatts_addr[6];
82
83 #endif /* defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE */
84
85 static bool g_host_init = false;
86
bt_mesh_host_init(void)87 int bt_mesh_host_init(void)
88 {
89 int rc;
90
91 if (g_host_init == true) {
92 BT_WARN("Already initialized host for mesh!");
93 return -EALREADY;
94 }
95
96 rc = btc_init();
97 if (rc != 0) {
98 return -1;
99 }
100
101 rc = osi_alarm_create_mux();
102 if (rc != 0) {
103 return -1;
104 }
105
106 osi_alarm_init();
107 g_host_init = true;
108
109 return 0;
110 }
111
bt_mesh_host_deinit(void)112 int bt_mesh_host_deinit(void)
113 {
114 int rc;
115
116 if (g_host_init == false) {
117 return -EALREADY;
118 }
119
120 osi_alarm_deinit();
121
122 rc = osi_alarm_delete_mux();
123 if (rc != 0) {
124 return -1;
125 }
126
127 btc_deinit();
128
129 g_host_init = false;
130
131 return 0;
132 }
133
134 uint8_t ble_hs_hci_get_hci_version(void);
135
bt_mesh_hci_init(void)136 void bt_mesh_hci_init(void)
137 {
138 /**
139 * Currently 20ms non-connectable adv interval is supported, and we need to add
140 * a flag to indicate this support.
141 */
142 #ifdef CONFIG_BLE_MESH_HCI_5_0
143 bt_mesh_dev.hci_version = BLE_MESH_HCI_VERSION_5_0;
144 #else
145 bt_mesh_dev.hci_version = ble_hs_hci_get_hci_version();
146 #endif
147 return;
148 }
149
150 static struct ble_gap_disc_params scan_param;
151 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
152 CONFIG_BLE_MESH_GATT_PROXY_CLIENT
153 static struct gattc_prov_info {
154 /* Service to be found depends on the type of adv pkt received */
155 struct bt_mesh_conn conn;
156 bt_mesh_addr_t addr;
157 uint16_t service_uuid;
158 uint16_t mtu;
159 bool wr_desc_done; /* Indicate if write char descriptor event is received */
160 uint16_t start_handle; /* Service attribute start handle */
161 uint16_t end_handle; /* Service attribute end handle */
162 uint16_t data_in_handle; /* Data In Characteristic attribute handle */
163 uint16_t data_out_handle; /* Data Out Characteristic attribute handle */
164 uint16_t ccc_handle; /* Data Out Characteristic CCC attribute handle */
165 } bt_mesh_gattc_info[BLE_MESH_MAX_CONN];
166
167 static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb;
168
ble_on_subscribe(uint16_t conn_handle,const struct ble_gatt_error * error,struct ble_gatt_attr * attr,void * arg)169 static int ble_on_subscribe(uint16_t conn_handle,
170 const struct ble_gatt_error *error,
171 struct ble_gatt_attr *attr,
172 void *arg)
173 {
174 struct bt_mesh_conn *conn = NULL;
175 uint8_t value[2] = {0x01, 0x00};
176 int i = (int)arg, j, len;
177 MODLOG_DFLT(INFO, "Subscribe complete; status=%d conn_handle=%d "
178 "attr_handle=%d\n",
179 error->status, conn_handle, attr->handle);
180
181 for (j = i + 1; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) {
182 if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].ccc_handle) {
183 break;
184 }
185 }
186 if (j == ARRAY_SIZE(bt_mesh_gattc_info)) {
187
188 conn = &bt_mesh_gattc_info[i].conn;
189
190 if (bt_mesh_gattc_info[i].ccc_handle != attr->handle) {
191 BT_WARN("gattc ccc_handle not matched");
192 bt_mesh_gattc_disconnect(conn);
193 return 0;
194 }
195
196 if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
197 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_write_descr != NULL) {
198 len = bt_mesh_gattc_conn_cb->prov_write_descr(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn);
199 if (len < 0) {
200 BT_ERR("prov_write_descr failed");
201 bt_mesh_gattc_disconnect(conn);
202 return 0;
203 }
204 bt_mesh_gattc_info[i].wr_desc_done = true;
205 }
206 } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) {
207 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_write_descr != NULL) {
208 len = bt_mesh_gattc_conn_cb->proxy_write_descr(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn);
209 if (len < 0) {
210 BT_ERR("proxy_write_descr failed");
211 bt_mesh_gattc_disconnect(conn);
212 return 0;
213 }
214 bt_mesh_gattc_info[i].wr_desc_done = true;
215 }
216 }
217
218
219 return 0;
220 }
221
222 ble_gattc_write_flat(conn_handle, bt_mesh_gattc_info[i].ccc_handle, value, sizeof(value), ble_on_subscribe, (void *)j);
223 return 0;
224 }
225
dsc_disced(uint16_t conn_handle,const struct ble_gatt_error * error,uint16_t chr_val_handle,const struct ble_gatt_dsc * dsc,void * arg)226 static int dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
227 uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
228 void *arg)
229 {
230 int rc = 0, j, i = (int)arg; /* char index */
231 uint8_t value[2] = {0x01, 0x00};
232
233 switch (error->status) {
234 case 0:
235 if (bt_mesh_gattc_info[i].ccc_handle == 0 && dsc &&
236 BLE_UUID16(&dsc->uuid)->value == BLE_MESH_UUID_GATT_CCC_VAL) {
237 bt_mesh_gattc_info[i].ccc_handle = dsc->handle;
238 }
239 break;
240
241 case BLE_HS_EDONE:
242 /* All descriptors in this characteristic discovered; start discovering
243 * descriptors in the next characteristic.
244 */
245 for (j = i + 1; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) {
246 if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].data_out_handle) {
247 break;
248 }
249 }
250 if (j == ARRAY_SIZE(bt_mesh_gattc_info)) {
251 /* Register Notification for Mesh Provisioning/Proxy Data Out Characteristic */
252 for (j = 0; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) {
253 if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].ccc_handle) {
254 break;
255 }
256 }
257 if (j == ARRAY_SIZE(bt_mesh_gattc_info)) {
258 return 0;
259 }
260 ble_gattc_write_flat(conn_handle, bt_mesh_gattc_info[i].ccc_handle, value, sizeof(value), ble_on_subscribe, (void *)j);
261 } else {
262 ble_gattc_disc_all_dscs(conn_handle, bt_mesh_gattc_info[j].data_out_handle, 0xffff, dsc_disced, (void *)j);
263 }
264 rc = 0;
265 break;
266
267 default:
268 /* Error; abort discovery. */
269 rc = error->status;
270 break;
271 }
272
273 return rc;
274 }
275
276
chr_disced(uint16_t conn_handle,const struct ble_gatt_error * error,const struct ble_gatt_chr * chr,void * arg)277 static int chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
278 const struct ble_gatt_chr *chr, void *arg)
279 {
280 int rc = 0, j;
281 uint16_t uuid16 = 0;
282 int i = (int)arg; /* service index */
283 struct bt_mesh_conn *conn = &bt_mesh_gattc_info[i].conn;
284 const ble_uuid_any_t *uuid = &chr->uuid;
285 if (chr) {
286 uuid16 = (uint16_t) BLE_UUID16(uuid)->value;
287 }
288 switch (error->status) {
289 case 0:
290 /* Get Mesh Provisioning/Proxy Data In/Out Characteristic */
291 if ((uuid16 == BLE_MESH_UUID_MESH_PROV_DATA_IN_VAL) || (uuid16 == BLE_MESH_UUID_MESH_PROXY_DATA_IN_VAL)) {
292 if (!(chr->properties & BLE_MESH_GATT_CHRC_WRITE_WITHOUT_RESP)) {
293 bt_mesh_gattc_disconnect(conn);
294 BT_ERR("Write without response is not set for Data In characteristic");
295 return 0;
296 }
297 bt_mesh_gattc_info[i].data_in_handle = chr->val_handle;
298 } else if ((uuid16 == BLE_MESH_UUID_MESH_PROV_DATA_OUT_VAL) || (uuid16 == BLE_MESH_UUID_MESH_PROXY_DATA_OUT_VAL)) {
299 if (!(chr->properties & BLE_MESH_GATT_CHRC_NOTIFY)) {
300 bt_mesh_gattc_disconnect(conn);
301 BT_ERR("Notify is not set for Data Out characteristic");
302 return 0;
303 }
304 bt_mesh_gattc_info[i].data_out_handle = chr->val_handle;
305 }
306 break;
307 case BLE_HS_EDONE:
308 /* All characteristics in this service discovered; start discovering
309 * characteristics in the next service.
310 */
311 for (j = i + 1; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) {
312 if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && (bt_mesh_gattc_info[j].start_handle > bt_mesh_gattc_info[j].end_handle)) {
313 break;
314 }
315 }
316 if (j == ARRAY_SIZE(bt_mesh_gattc_info)) {
317 for (j = 0; j < ARRAY_SIZE(bt_mesh_gattc_info); j++) {
318 if ((bt_mesh_gattc_info[j].conn.handle == conn_handle) && bt_mesh_gattc_info[j].data_out_handle) {
319 break;
320 }
321 }
322 ble_gattc_disc_all_dscs(conn_handle, bt_mesh_gattc_info[j].data_out_handle, bt_mesh_gattc_info[j].end_handle,
323 dsc_disced, (void *)j);
324 } else {
325 ble_gattc_disc_all_chrs(conn_handle, bt_mesh_gattc_info[j].start_handle, bt_mesh_gattc_info[j].end_handle,
326 chr_disced, (void *)j);
327 }
328 break;
329
330 default:
331 rc = error->status;
332 break;
333 }
334
335 return rc;
336 }
337
338
svc_disced(uint16_t conn_handle,const struct ble_gatt_error * error,const struct ble_gatt_svc * service,void * arg)339 static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
340 const struct ble_gatt_svc *service, void *arg)
341 {
342 struct bt_mesh_conn *conn = NULL;
343 int rc = 0, i;
344 const ble_uuid_any_t *uuid;
345 uint8_t uuid_length;
346 switch (error->status) {
347 case 0:
348 if (!service) {
349 return 0;
350 }
351 uuid = &service->uuid;
352 uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16);
353 if (uuid_length != 2) {
354 return 0;
355 }
356 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
357 if (bt_mesh_gattc_info[i].service_uuid == (uint16_t)BLE_UUID16(uuid)->value) {
358 bt_mesh_gattc_info[i].start_handle = service->start_handle;
359 bt_mesh_gattc_info[i].end_handle = service->end_handle;
360 break;
361 }
362 }
363
364 break;
365 case BLE_HS_EDONE:
366 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
367 if (bt_mesh_gattc_info[i].conn.handle == conn_handle) {
368 break;
369 }
370 }
371
372 if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
373 BT_ERR("Conn handle 0x%04x not found", conn_handle);
374 return 0;
375 }
376 conn = &bt_mesh_gattc_info[i].conn;
377 if (bt_mesh_gattc_info[i].start_handle == 0x00 ||
378 bt_mesh_gattc_info[i].end_handle == 0x00 ||
379 (bt_mesh_gattc_info[i].start_handle > bt_mesh_gattc_info[i].end_handle)) {
380 bt_mesh_gattc_disconnect(conn);
381 return 0;
382 }
383
384 /* Get the characteristic num within Mesh Provisioning/Proxy Service */
385 ble_gattc_disc_all_chrs(conn_handle, bt_mesh_gattc_info[i].start_handle, bt_mesh_gattc_info[i].end_handle,
386 chr_disced, (void *)i);
387 break;
388
389 default:
390 rc = error->status;
391 break;
392 }
393
394 return rc;
395 }
396
397
398 #endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
399
disc_cb(struct ble_gap_event * event,void * arg)400 static int disc_cb(struct ble_gap_event *event, void *arg)
401 {
402 struct ble_gap_disc_desc *desc;
403
404 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
405 CONFIG_BLE_MESH_GATT_PROXY_CLIENT
406 int rc, i;
407 uint8_t notif_data[100];
408 uint16_t notif_len;
409 ssize_t len;
410 struct ble_gap_conn_desc conn_desc;
411 struct bt_mesh_conn *conn = NULL;
412 #endif
413
414 switch (event->type) {
415 case BLE_GAP_EVENT_DISC: {
416 struct net_buf_simple buf = {0};
417
418 desc = &event->disc;
419 net_buf_simple_init_with_data(&buf, (void *)desc->data, desc->length_data);
420
421 if (bt_mesh_scan_dev_found_cb) {
422 bt_mesh_scan_dev_found_cb((bt_mesh_addr_t *)&desc->addr, desc->rssi, desc->event_type, &buf);
423 }
424 break;
425 }
426 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
427 CONFIG_BLE_MESH_GATT_PROXY_CLIENT
428 case BLE_GAP_EVENT_CONNECT:
429 if (event->connect.status == 0) {
430 /* Connection successfully established. */
431 MODLOG_DFLT(INFO, "Connection established ");
432
433 rc = ble_gap_conn_find(event->connect.conn_handle, &conn_desc);
434 assert(rc == 0);
435
436 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->connected != NULL) {
437 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
438 if (!memcmp(bt_mesh_gattc_info[i].addr.val, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN)) {
439 bt_mesh_gattc_info[i].conn.handle = event->connect.conn_handle;
440 (bt_mesh_gattc_conn_cb->connected)(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, i);
441 break;
442 }
443 }
444 }
445 }
446 if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
447 rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
448 if (rc != 0) {
449 BT_ERR("Invalid scan status %d", rc);
450 break;
451 }
452 bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
453 }
454 break;
455 case BLE_GAP_EVENT_DISCONNECT:
456 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->disconnected != NULL) {
457 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
458 memcpy(&conn_desc, &event->disconnect.conn, sizeof(conn_desc));
459 if (!memcmp(bt_mesh_gattc_info[i].addr.val, conn_desc.peer_ota_addr.val, BLE_MESH_ADDR_LEN)) {
460 if (bt_mesh_gattc_info[i].conn.handle == event->disconnect.conn.conn_handle) {
461 (bt_mesh_gattc_conn_cb->disconnected)(&bt_mesh_gattc_info[i].addr, &bt_mesh_gattc_info[i].conn, event->disconnect.reason);
462 if (!bt_mesh_gattc_info[i].wr_desc_done) {
463 /* Add this in case connection is established, connected event comes, but
464 * connection is terminated before server->filter_type is set to PROV.
465 */
466 #if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
467 if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
468 bt_mesh_provisioner_clear_link_info(bt_mesh_gattc_info[i].addr.val);
469 }
470 #endif
471 }
472 } else {
473 /* Add this in case connection is failed to be established, and here we
474 * need to clear some provision link info, like connecting flag, device
475 * uuid, address info, etc.
476 */
477 #if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
478 if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
479 bt_mesh_provisioner_clear_link_info(bt_mesh_gattc_info[i].addr.val);
480 }
481 #endif
482 }
483 #if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
484 if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
485 /* Decrease prov pbg_count */
486 bt_mesh_provisioner_pbg_count_dec();
487 }
488 #endif
489 /* Reset corresponding gattc info */
490 memset(&bt_mesh_gattc_info[i], 0, sizeof(bt_mesh_gattc_info[i]));
491 bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
492 bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT;
493 bt_mesh_gattc_info[i].wr_desc_done = false;
494 break;
495 }
496 }
497 }
498 break;
499 case BLE_GAP_EVENT_MTU:
500 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
501 if (bt_mesh_gattc_info[i].conn.handle == event->mtu.conn_handle) {
502 bt_mesh_gattc_info[i].mtu = event->mtu.value;
503 break;
504 }
505 }
506 /** Once mtu exchanged accomplished, start to find services, and here
507 * need a flag to indicate which service to find(Mesh Prov Service or
508 * Mesh Proxy Service)
509 */
510 ble_uuid_any_t bt_uuid;
511 if (i != ARRAY_SIZE(bt_mesh_gattc_info)) {
512 //service_uuid.len = sizeof(bt_mesh_gattc_info[i].service_uuid);
513 if (sizeof(bt_mesh_gattc_info[i].service_uuid) == 0x02) {
514 bt_uuid.u16.u.type = BLE_UUID_TYPE_16;
515 bt_uuid.u16.value = bt_mesh_gattc_info[i].service_uuid;
516
517 } else if (sizeof(bt_mesh_gattc_info[i].service_uuid) == 0x10) {
518 bt_uuid.u128.u.type = BLE_UUID_TYPE_128;
519 memcpy(bt_uuid.u128.value, &bt_mesh_gattc_info[i].service_uuid, 16);
520 }
521 /* Search Mesh Provisioning Service or Mesh Proxy Service */
522 ble_gattc_disc_all_svcs(bt_mesh_gattc_info[i].conn.handle, svc_disced, NULL);
523 }
524 break;
525 case BLE_GAP_EVENT_NOTIFY_RX:
526 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
527 if (bt_mesh_gattc_info[i].conn.handle == event->notify_rx.conn_handle) {
528 break;
529 }
530 }
531
532 if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
533 BT_ERR("Conn handle 0x%04x not found", event->notify_rx.conn_handle);
534 return 0;
535 }
536
537 conn = &bt_mesh_gattc_info[i].conn;
538 ble_gap_conn_find(event->notify_rx.conn_handle, &conn_desc);
539
540 if (bt_mesh_gattc_info[i].data_out_handle != event->notify_rx.attr_handle) {
541 /* Data isn't populated yet */
542 return 0;
543 }
544
545 if (memcmp(bt_mesh_gattc_info[i].addr.val, conn_desc.peer_id_addr.val, BLE_MESH_ADDR_LEN) ||
546 (bt_mesh_gattc_info[i].data_out_handle != event->notify_rx.attr_handle) ||
547 (event->notify_rx.indication != 0)) {
548 BT_ERR("Notification error");
549 bt_mesh_gattc_disconnect(conn);
550 return 0;
551 }
552
553 notif_len = OS_MBUF_PKTLEN(event->notify_rx.om);
554 rc = os_mbuf_copydata(event->notify_rx.om, 0, notif_len, notif_data);
555
556 if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
557 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_notify != NULL) {
558 len = bt_mesh_gattc_conn_cb->prov_notify(&bt_mesh_gattc_info[i].conn,
559 notif_data, notif_len);
560 if (len < 0) {
561 BT_ERR("prov_notify failed");
562 bt_mesh_gattc_disconnect(conn);
563 return 0;
564 }
565 }
566 } else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) {
567 if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL &&
568 bt_mesh_gattc_info[i].wr_desc_done) {
569 len = bt_mesh_gattc_conn_cb->proxy_notify(&bt_mesh_gattc_info[i].conn,
570 notif_data, notif_len);
571 if (len < 0) {
572 BT_ERR("proxy_notify failed");
573 bt_mesh_gattc_disconnect(conn);
574 return 0;
575 }
576 }
577 }
578 break;
579 #endif
580 default:
581 break;
582 }
583
584 return 0;
585 }
586
start_le_scan(uint8_t scan_type,uint16_t interval,uint16_t window,uint8_t filter_dup)587 static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, uint8_t filter_dup)
588 {
589
590 scan_param.filter_duplicates = filter_dup;
591 scan_param.itvl = interval;
592 scan_param.window = window;
593
594 if (scan_type == BLE_MESH_SCAN_PASSIVE) {
595 scan_param.passive = 1;
596 } else {
597 scan_param.passive = 0;
598 }
599 ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
600
601 #if BLE_MESH_DEV
602 if (scan_type == BLE_MESH_SCAN_ACTIVE) {
603 bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ACTIVE_SCAN);
604 } else {
605 bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ACTIVE_SCAN);
606 }
607 #endif
608
609 return 0;
610 }
611
set_ad(const struct bt_mesh_adv_data * ad,size_t ad_len,uint8_t * buf,uint8_t * buf_len)612 static int set_ad(const struct bt_mesh_adv_data *ad, size_t ad_len, uint8_t *buf, uint8_t *buf_len)
613 {
614 int i;
615
616 for (i = 0; i < ad_len; i++) {
617 buf[(*buf_len)++] = ad[i].data_len + 1;
618 buf[(*buf_len)++] = ad[i].type;
619
620 memcpy(&buf[*buf_len], ad[i].data,
621 ad[i].data_len);
622 *buf_len += ad[i].data_len;
623 }
624
625 return 0;
626 }
627
628 #if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE
629 static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(uint16_t handle);
630
gap_event_cb(struct ble_gap_event * event,void * arg)631 static int gap_event_cb(struct ble_gap_event *event, void *arg)
632 {
633 struct ble_gap_conn_desc desc;
634 int rc;
635
636 switch (event->type) {
637 case BLE_GAP_EVENT_CONNECT:
638 /* A new connection was established or a connection attempt failed. */
639 MODLOG_DFLT(INFO, "connection %s; status=%d ",
640 event->connect.status == 0 ? "established" : "failed",
641 event->connect.status);
642 if (event->connect.status == 0) {
643 rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
644 assert(rc == 0);
645 }
646 MODLOG_DFLT(INFO, "\n");
647 #if BLE_MESH_DEV
648 /* When connection is created, advertising will be stopped automatically. */
649 bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
650 #endif
651 if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->connected != NULL) {
652 uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
653 if (index < BLE_MESH_MAX_CONN) {
654 bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
655 (bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
656 }
657 memcpy(bt_mesh_gatts_addr, desc.peer_id_addr.val, BLE_MESH_ADDR_LEN);
658 /* This is for EspBleMesh Android app. When it tries to connect with the
659 * device at the first time and it fails due to some reason. And after
660 * the second connection, the device needs to send GATT service change
661 * indication to the phone manually to notify it discovering service again.
662 */
663 ble_svc_gatt_changed(prov_svc_start_handle, 0xffff);
664
665 }
666
667 return 0;
668
669 case BLE_GAP_EVENT_DISCONNECT:
670 MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
671 MODLOG_DFLT(INFO, "\n");
672 #if BLE_MESH_DEV
673 bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
674 #endif
675 if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->disconnected != NULL) {
676 uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
677 if (index < BLE_MESH_MAX_CONN) {
678 bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
679 (bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason);
680 }
681 memset(bt_mesh_gatts_addr, 0x0, BLE_MESH_ADDR_LEN);
682 }
683
684 return 0;
685
686 case BLE_GAP_EVENT_CONN_UPDATE:
687 /* The central has updated the connection parameters. */
688 MODLOG_DFLT(INFO, "connection updated; status=%d ",
689 event->conn_update.status);
690 rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
691 assert(rc == 0);
692 MODLOG_DFLT(INFO, "\n");
693 return 0;
694
695 case BLE_GAP_EVENT_ADV_COMPLETE:
696 MODLOG_DFLT(INFO, "advertise complete; reason=%d",
697 event->adv_complete.reason);
698 return 0;
699
700 case BLE_GAP_EVENT_ENC_CHANGE:
701 /* Encryption has been enabled or disabled for this connection. */
702 MODLOG_DFLT(INFO, "encryption change event; status=%d ",
703 event->enc_change.status);
704 rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
705 assert(rc == 0);
706 MODLOG_DFLT(INFO, "\n");
707 return 0;
708
709 case BLE_GAP_EVENT_SUBSCRIBE:
710 MODLOG_DFLT(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
711 "reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
712 event->subscribe.conn_handle,
713 event->subscribe.attr_handle,
714 event->subscribe.reason,
715 event->subscribe.prev_notify,
716 event->subscribe.cur_notify,
717 event->subscribe.prev_indicate,
718 event->subscribe.cur_indicate);
719 struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(event->subscribe.attr_handle + 1);
720 uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle);
721 uint16_t len = 0;
722 uint16_t ccc_val = 0;
723
724 if (event->subscribe.prev_notify != event->subscribe.cur_notify) {
725 ccc_val = event->subscribe.cur_notify;
726 } else if (event->subscribe.prev_indicate != event->subscribe.cur_indicate) {
727 if (event->subscribe.cur_indicate) {
728 ccc_val = 2;
729 } else {
730 ccc_val = 0;
731 }
732 }
733
734 if (attr != NULL && attr->write != NULL) {
735 if ((len = attr->write(&bt_mesh_gatts_conn[index], attr,
736 &ccc_val,
737 sizeof(ccc_val),
738 0 /* offset */, 0)) > 0) {
739 }
740 }
741
742 return 0;
743
744 case BLE_GAP_EVENT_MTU:
745 MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
746 event->mtu.conn_handle,
747 event->mtu.channel_id,
748 event->mtu.value);
749 return 0;
750
751 case BLE_GAP_EVENT_REPEAT_PAIRING:
752 /* We already have a bond with the peer, but it is attempting to
753 * establish a new secure link. This app sacrifices security for
754 * convenience: just throw away the old bond and accept the new link.
755 */
756
757 /* Delete the old bond. */
758 rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
759 assert(rc == 0);
760 ble_store_util_delete_peer(&desc.peer_id_addr);
761
762 /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
763 * continue with the pairing operation.
764 */
765 return BLE_GAP_REPEAT_PAIRING_RETRY;
766
767 case BLE_GAP_EVENT_PASSKEY_ACTION:
768 MODLOG_DFLT(INFO, "PASSKEY_ACTION_EVENT started \n");
769 return 0;
770 }
771
772 return 0;
773 }
774 #else
775
gap_event_cb(struct ble_gap_event * event,void * arg)776 static int gap_event_cb(struct ble_gap_event *event, void *arg)
777 {
778 return 0;
779 }
780 #endif
781
782 /* 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)783 int bt_le_adv_start(const struct bt_mesh_adv_param *param,
784 const struct bt_mesh_adv_data *ad, size_t ad_len,
785 const struct bt_mesh_adv_data *sd, size_t sd_len)
786 {
787 struct ble_gap_adv_params adv_params;
788 uint8_t buf[BLE_HS_ADV_MAX_SZ];
789 uint16_t interval = 0;
790 uint8_t buf_len = 0;
791 int err;
792
793 #if BLE_MESH_DEV
794 if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
795 return -EALREADY;
796 }
797 #endif
798
799 err = set_ad(ad, ad_len, buf, &buf_len);
800 if (err) {
801 BT_ERR("set_ad failed: err %d", err);
802 return err;
803 }
804
805 err = ble_gap_adv_set_data(buf, buf_len);
806 if (err != 0) {
807 BT_ERR("Advertising set failed: err %d", err);
808 return err;
809 }
810
811 if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
812 buf_len = 0;
813
814 err = set_ad(sd, sd_len, buf, &buf_len);
815 if (err) {
816 BT_ERR("set_ad failed: err %d", err);
817 return err;
818 }
819
820 err = ble_gap_adv_rsp_set_data(buf, buf_len);
821 if (err != 0) {
822 BT_ERR("Scan rsp failed: err %d", err);
823 return err;
824 }
825 }
826
827 memset(&adv_params, 0, sizeof adv_params);
828
829 if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) {
830 adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
831 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
832 } else if (sd != NULL) {
833 adv_params.conn_mode = BLE_GAP_CONN_MODE_NON;
834 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
835 } else {
836 adv_params.conn_mode = BLE_GAP_CONN_MODE_NON;
837 adv_params.disc_mode = BLE_GAP_DISC_MODE_NON;
838 }
839
840 interval = param->interval_min;
841
842 #if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL
843 /* If non-connectable mesh packets are transmitted with an adv interval
844 * not smaller than 10ms, then we will use a random adv interval between
845 * [interval / 2, interval] for them.
846 */
847 if (adv_params.conn_mode == BLE_GAP_CONN_MODE_NON &&
848 adv_params.disc_mode == BLE_GAP_DISC_MODE_NON && interval >= 16) {
849 interval >>= 1;
850 interval += (bt_mesh_get_rand() % (interval + 1));
851
852 BT_INFO("%u->%u", param->interval_min, interval);
853 }
854 #endif
855
856 adv_params.itvl_min = interval;
857 adv_params.itvl_max = interval;
858
859 again:
860 err = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params,
861 gap_event_cb, NULL);
862 if (err) {
863 if (err == BLE_HS_EALREADY) {
864 ble_gap_adv_stop();
865 goto again;
866 }
867
868 BT_ERR("Advertising start failed: err %d", err);
869 return err;
870 }
871
872 #if BLE_MESH_DEV
873 bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
874
875 if (!(param->options & BLE_MESH_ADV_OPT_ONE_TIME)) {
876 bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
877 }
878 #endif
879
880 return 0;
881 }
882
883 #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)884 int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
885 const struct bt_mesh_ble_adv_data *data)
886 {
887 struct ble_gap_adv_params adv_params = {0};
888 ble_addr_t p_dir_bda = {0};
889 int err = 0;
890
891 if (data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
892 param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
893 if (data->adv_data_len) {
894 err = ble_gap_adv_set_data(data->adv_data, data->adv_data_len);
895 if (err) {
896 BT_ERR("Failed to set advertising data, err %d", err);
897 return err;
898 }
899 }
900 if (data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
901 err = ble_gap_adv_rsp_set_data(data->scan_rsp_data, data->scan_rsp_data_len);
902 if (err) {
903 BT_ERR("Failed to set scan rsp data, err %d", err);
904 return err;
905 }
906 }
907 }
908
909 switch (param->adv_type) {
910 case BLE_MESH_ADV_IND:
911 adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
912 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
913 break;
914 case BLE_MESH_ADV_DIRECT_IND:
915 adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR;
916 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
917 break;
918 case BLE_MESH_ADV_SCAN_IND:
919 adv_params.conn_mode = BLE_GAP_CONN_MODE_NON;
920 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
921 break;
922 case BLE_MESH_ADV_NONCONN_IND:
923 adv_params.conn_mode = BLE_GAP_CONN_MODE_NON;
924 adv_params.disc_mode = BLE_GAP_DISC_MODE_NON;
925 break;
926 case BLE_MESH_ADV_DIRECT_IND_LOW_DUTY:
927 adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR;
928 adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
929 break;
930 }
931 adv_params.itvl_min = param->interval;
932 adv_params.itvl_max = param->interval;
933 adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
934 adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
935 adv_params.high_duty_cycle = (param->adv_type == BLE_MESH_ADV_DIRECT_IND) ? true : false;
936
937 if (param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
938 param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
939 param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
940 param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
941 p_dir_bda.type = param->peer_addr_type;
942 memcpy(p_dir_bda.val, param->peer_addr, BLE_MESH_ADDR_LEN);
943 }
944
945 err = ble_gap_adv_start(param->own_addr_type, &p_dir_bda, BLE_HS_FOREVER, &adv_params,
946 gap_event_cb, NULL);
947 if (err) {
948 BT_ERR("Failed to start advertising, err %d", err);
949 return err;
950 }
951
952 return 0;
953 }
954 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
955
bt_le_adv_stop(void)956 int bt_le_adv_stop(void)
957 {
958 #if BLE_MESH_DEV
959 bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
960 if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
961 return 0;
962 }
963 #endif
964 ble_gap_adv_stop();
965
966 #if BLE_MESH_DEV
967 bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
968 #endif
969
970 return 0;
971 }
972
bt_le_scan_start(const struct bt_mesh_scan_param * param,bt_mesh_scan_cb_t cb)973 int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb)
974 {
975 int err;
976
977 if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
978 BT_INFO("Scan is already started");
979 return -EALREADY;
980 }
981
982 #if BLE_MESH_DEV
983 if (param->filter_dup) {
984 bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCAN_FILTER_DUP);
985 } else {
986 bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCAN_FILTER_DUP);
987 }
988 #endif
989
990 err = start_le_scan(param->type, param->interval, param->window, param->filter_dup);
991 if (err) {
992 return err;
993 }
994
995 bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
996 bt_mesh_scan_dev_found_cb = cb;
997
998 return 0;
999 }
1000
bt_le_scan_stop(void)1001 int bt_le_scan_stop(void)
1002 {
1003 if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
1004 BT_INFO("Scan is already stopped");
1005 return -EALREADY;
1006 }
1007
1008 ble_gap_disc_cancel();
1009
1010 bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
1011 bt_mesh_scan_dev_found_cb = NULL;
1012
1013 return 0;
1014 }
1015
1016 #if CONFIG_BLE_MESH_TEST_USE_WHITE_LIST
bt_le_update_white_list(struct bt_mesh_white_list * wl)1017 int bt_le_update_white_list(struct bt_mesh_white_list *wl)
1018 {
1019 ble_addr_t addr = {0};
1020
1021 if (wl == NULL || wl->add_remove == false) {
1022 BT_ERR("%s, Invalid parameter", __func__);
1023 return -EINVAL;
1024 }
1025
1026 addr.type = wl->addr_type;
1027 memcpy(addr.val, wl->remote_bda, BLE_MESH_ADDR_LEN);
1028
1029 return ble_gap_wl_set(&addr, 1);
1030 }
1031 #endif
1032
1033 #if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE
1034
bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb * cb)1035 void bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb *cb)
1036 {
1037 bt_mesh_gatts_conn_cb = cb;
1038 }
1039
bt_mesh_gatts_conn_cb_deregister(void)1040 void bt_mesh_gatts_conn_cb_deregister(void)
1041 {
1042 bt_mesh_gatts_conn_cb = NULL;
1043 }
1044
bt_mesh_gatts_find_attr_by_handle(uint16_t handle)1045 static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(uint16_t handle)
1046 {
1047 struct bt_mesh_gatt_service *svc = NULL;
1048 struct bt_mesh_gatt_attr *attr = NULL;
1049
1050 SYS_SLIST_FOR_EACH_CONTAINER(&bt_mesh_gatts_db, svc, node) {
1051 int i;
1052
1053 for (i = 0; i < svc->attr_count; i++) {
1054 attr = &svc->attrs[i];
1055 /* Check the attrs handle is equal to the handle or not */
1056 if (attr->handle == handle) {
1057 return attr;
1058 }
1059 }
1060 }
1061
1062 return NULL;
1063 }
1064
bt_mesh_gatts_foreach_attr(uint16_t start_handle,uint16_t end_handle,bt_mesh_gatt_attr_func_t func,void * user_data)1065 static void bt_mesh_gatts_foreach_attr(uint16_t start_handle, uint16_t end_handle,
1066 bt_mesh_gatt_attr_func_t func, void *user_data)
1067 {
1068 struct bt_mesh_gatt_service *svc = NULL;
1069
1070 SYS_SLIST_FOR_EACH_CONTAINER(&bt_mesh_gatts_db, svc, node) {
1071 int i;
1072
1073 for (i = 0; i < svc->attr_count; i++) {
1074 struct bt_mesh_gatt_attr *attr = &svc->attrs[i];
1075
1076 /* Check if attribute handle is within range */
1077 if (attr->handle < start_handle ||
1078 attr->handle > end_handle) {
1079 continue;
1080 }
1081
1082 if (func(attr, user_data) == BLE_MESH_GATT_ITER_STOP) {
1083 return;
1084 }
1085 }
1086 }
1087 }
1088
find_next(const struct bt_mesh_gatt_attr * attr,void * user_data)1089 static uint8_t find_next(const struct bt_mesh_gatt_attr *attr, void *user_data)
1090 {
1091 struct bt_mesh_gatt_attr **next = user_data;
1092
1093 *next = (struct bt_mesh_gatt_attr *)attr;
1094
1095 return BLE_MESH_GATT_ITER_STOP;
1096 }
1097
bt_mesh_gatts_attr_next(const struct bt_mesh_gatt_attr * attr)1098 static struct bt_mesh_gatt_attr *bt_mesh_gatts_attr_next(const struct bt_mesh_gatt_attr *attr)
1099 {
1100 struct bt_mesh_gatt_attr *next = NULL;
1101
1102 bt_mesh_gatts_foreach_attr(attr->handle + 1, attr->handle + 1, find_next, &next);
1103
1104 return next;
1105 }
1106
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)1107 ssize_t bt_mesh_gatts_attr_read(struct bt_mesh_conn *conn,
1108 const struct bt_mesh_gatt_attr *attr,
1109 void *buf, uint16_t buf_len, uint16_t offset,
1110 const void *value, uint16_t value_len)
1111 {
1112 uint16_t len;
1113
1114 if (offset > value_len) {
1115 return BLE_MESH_GATT_ERR(BLE_MESH_ATT_ERR_INVALID_OFFSET);
1116 }
1117
1118 len = MIN(buf_len, value_len - offset);
1119
1120 BT_DBG("handle 0x%04x offset %u length %u", attr->handle, offset, len);
1121
1122 memcpy(buf, value + offset, len);
1123
1124 return len;
1125 }
1126
1127 struct gatts_incl {
1128 uint16_t start_handle;
1129 uint16_t end_handle;
1130 uint16_t uuid16;
1131 } __packed;
1132
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)1133 ssize_t bt_mesh_gatts_attr_read_included(struct bt_mesh_conn *conn,
1134 const struct bt_mesh_gatt_attr *attr,
1135 void *buf, uint16_t len, uint16_t offset)
1136 {
1137 struct bt_mesh_gatt_attr *incl = attr->user_data;
1138 struct bt_mesh_uuid *uuid = incl->user_data;
1139 struct gatts_incl pdu = {0};
1140 uint8_t value_len;
1141
1142 /* First attr points to the start handle */
1143 pdu.start_handle = sys_cpu_to_le16(incl->handle);
1144 value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle);
1145
1146 /*
1147 * Core 4.2, Vol 3, Part G, 3.2,
1148 * The Service UUID shall only be present when the UUID is a 16-bit Bluetooth UUID.
1149 */
1150 if (uuid->type == BLE_MESH_UUID_TYPE_16) {
1151 pdu.uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(uuid)->val);
1152 value_len += sizeof(pdu.uuid16);
1153 }
1154
1155 return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
1156 }
1157
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)1158 ssize_t bt_mesh_gatts_attr_read_service(struct bt_mesh_conn *conn,
1159 const struct bt_mesh_gatt_attr *attr,
1160 void *buf, uint16_t len, uint16_t offset)
1161 {
1162 struct bt_mesh_uuid *uuid = attr->user_data;
1163
1164 if (uuid->type == BLE_MESH_UUID_TYPE_16) {
1165 uint16_t uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(uuid)->val);
1166
1167 return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &uuid16, 2);
1168 }
1169
1170 return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset,
1171 BLE_MESH_UUID_128(uuid)->val, 16);
1172 }
1173
1174 struct gatts_chrc {
1175 uint8_t properties;
1176 uint16_t value_handle;
1177 union {
1178 uint16_t uuid16;
1179 uint8_t uuid[16];
1180 };
1181 } __packed;
1182
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)1183 ssize_t bt_mesh_gatts_attr_read_chrc(struct bt_mesh_conn *conn,
1184 const struct bt_mesh_gatt_attr *attr,
1185 void *buf, uint16_t len, uint16_t offset)
1186 {
1187 struct bt_mesh_gatt_char *chrc = attr->user_data;
1188 const struct bt_mesh_gatt_attr *next = NULL;
1189 struct gatts_chrc pdu = {0};
1190 uint8_t value_len;
1191
1192 pdu.properties = chrc->properties;
1193 /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 534:
1194 * 3.3.2 Characteristic Value Declaration
1195 * The Characteristic Value declaration contains the value of the
1196 * characteristic. It is the first Attribute after the characteristic
1197 * declaration. All characteristic definitions shall have a
1198 * Characteristic Value declaration.
1199 */
1200 next = bt_mesh_gatts_attr_next(attr);
1201 if (!next) {
1202 BT_WARN("No value for characteristic, handle 0x%04x", attr->handle);
1203 pdu.value_handle = 0x0000;
1204 } else {
1205 pdu.value_handle = sys_cpu_to_le16(next->handle);
1206 }
1207 value_len = sizeof(pdu.properties) + sizeof(pdu.value_handle);
1208
1209 if (chrc->uuid->type == BLE_MESH_UUID_TYPE_16) {
1210 pdu.uuid16 = sys_cpu_to_le16(BLE_MESH_UUID_16(chrc->uuid)->val);
1211 value_len += 2;
1212 } else {
1213 memcpy(pdu.uuid, BLE_MESH_UUID_128(chrc->uuid)->val, 16);
1214 value_len += 16;
1215 }
1216
1217 return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
1218 }
1219
gatts_register(struct bt_mesh_gatt_service * svc)1220 static int gatts_register(struct bt_mesh_gatt_service *svc)
1221 {
1222 struct bt_mesh_gatt_service *last;
1223 uint16_t handle;
1224
1225 if (sys_slist_is_empty(&bt_mesh_gatts_db)) {
1226 handle = 0;
1227 goto populate;
1228 }
1229
1230 last = SYS_SLIST_PEEK_TAIL_CONTAINER(&bt_mesh_gatts_db, last, node);
1231 handle = last->attrs[last->attr_count - 1].handle;
1232 BT_DBG("gatts register, handle %d", handle);
1233
1234 ARG_UNUSED(handle);
1235
1236 populate:
1237 sys_slist_append(&bt_mesh_gatts_db, &svc->node);
1238 return 0;
1239 }
1240
gatts_deregister(struct bt_mesh_gatt_service * svc)1241 static int gatts_deregister(struct bt_mesh_gatt_service *svc)
1242 {
1243 if (sys_slist_is_empty(&bt_mesh_gatts_db)) {
1244 return 0;
1245 }
1246
1247 sys_slist_find_and_remove(&bt_mesh_gatts_db, &svc->node);
1248 return 0;
1249 }
1250
bt_mesh_gatts_service_register(struct bt_mesh_gatt_service * svc)1251 int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc)
1252 {
1253 uint16_t offset = 0;
1254 int i;
1255 if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) {
1256 offset = proxy_svc_start_handle;
1257 } else if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROV_VAL) {
1258 offset = prov_svc_start_handle;
1259 }
1260
1261 for (i = 0; i < svc->attr_count; i++) {
1262 svc->attrs[i].handle = offset + i;
1263 }
1264 gatts_register(svc);
1265 return 0;
1266 }
1267
bt_mesh_gatts_service_deregister(struct bt_mesh_gatt_service * svc)1268 int bt_mesh_gatts_service_deregister(struct bt_mesh_gatt_service *svc)
1269 {
1270 assert(svc != NULL);
1271
1272 gatts_deregister(svc);
1273
1274 return 0;
1275 }
1276
bt_mesh_gatts_disconnect(struct bt_mesh_conn * conn,uint8_t reason)1277 int bt_mesh_gatts_disconnect(struct bt_mesh_conn *conn, uint8_t reason)
1278 {
1279 uint16_t conn_id = BLE_MESH_GATT_CREATE_CONN_ID(conn->handle);
1280 ble_gap_terminate(conn_id, reason);
1281 return 0;
1282 }
1283
bt_mesh_gatts_service_unregister(struct bt_mesh_gatt_service * svc)1284 int bt_mesh_gatts_service_unregister(struct bt_mesh_gatt_service *svc)
1285 {
1286 assert(svc != NULL);
1287 BT_ERR("Unsupported for NimBLE host");
1288 return 0;
1289 }
1290
bt_mesh_gatts_notify(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,const void * data,uint16_t len)1291 int bt_mesh_gatts_notify(struct bt_mesh_conn *conn,
1292 const struct bt_mesh_gatt_attr *attr,
1293 const void *data, uint16_t len)
1294 {
1295 struct os_mbuf *om;
1296 uint16_t conn_id = BLE_MESH_GATT_CREATE_CONN_ID(conn->handle);
1297
1298 om = ble_hs_mbuf_from_flat(data, len);
1299 assert(om);
1300 ble_gatts_notify_custom(conn_id, attr->handle, om);
1301
1302 return 0;
1303 }
1304
bt_mesh_gatt_get_mtu(struct bt_mesh_conn * conn)1305 uint16_t bt_mesh_gatt_get_mtu(struct bt_mesh_conn *conn)
1306 {
1307 return ble_att_preferred_mtu();
1308 }
1309
1310 /* APIs added by Espressif */
bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service * svc)1311 int bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service *svc)
1312 {
1313 int rc;
1314 uint16_t handle;
1315
1316 if (!svc) {
1317 BT_ERR("%s, Invalid parameter", __func__);
1318 return -EINVAL;
1319 }
1320
1321 if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) {
1322 rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle);
1323 } else {
1324 rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle);
1325 }
1326
1327 assert(rc == 0);
1328 ble_gatts_svc_set_visibility(handle, 0);
1329
1330 /* FIXME: figure out end handle */
1331 ble_svc_gatt_changed(handle, 0xffff);
1332
1333 return 0;
1334 }
1335
bt_mesh_gatts_service_start(struct bt_mesh_gatt_service * svc)1336 int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc)
1337 {
1338 int rc;
1339 uint16_t handle;
1340
1341 if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) {
1342 rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle);
1343 } else {
1344 rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle);
1345 }
1346
1347 assert(rc == 0);
1348 ble_gatts_svc_set_visibility(handle, 1);
1349
1350 /* FIXME: figure out end handle */
1351 ble_svc_gatt_changed(handle, 0xffff);
1352
1353 return 0;
1354 }
1355
bt_mesh_gatts_set_local_device_name(const char * name)1356 int bt_mesh_gatts_set_local_device_name(const char *name)
1357 {
1358 return ble_svc_gap_device_name_set(name);
1359 }
1360 #endif /* defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE */
1361
1362 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
1363 CONFIG_BLE_MESH_GATT_PROXY_CLIENT
bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb * cb)1364 void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb)
1365 {
1366 bt_mesh_gattc_conn_cb = cb;
1367 }
1368
bt_mesh_gattc_conn_cb_deregister(void)1369 void bt_mesh_gattc_conn_cb_deregister(void)
1370 {
1371 bt_mesh_gattc_conn_cb = NULL;
1372 }
1373
bt_mesh_gattc_get_free_conn_count(void)1374 uint8_t bt_mesh_gattc_get_free_conn_count(void)
1375 {
1376 uint8_t count = 0;
1377 uint8_t i;
1378
1379 for (i = 0U; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1380 if (bt_mesh_gattc_info[i].conn.handle == 0xFFFF &&
1381 bt_mesh_gattc_info[i].service_uuid == 0x0000) {
1382 ++count;
1383 }
1384 }
1385
1386 return count;
1387 }
1388
bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn * conn)1389 uint16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
1390 {
1391 int i;
1392
1393 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1394 if (conn == &bt_mesh_gattc_info[i].conn) {
1395 break;
1396 }
1397 }
1398
1399 if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
1400 return 0;
1401 }
1402
1403 return bt_mesh_gattc_info[i].service_uuid;
1404 }
1405
1406 /** For provisioner acting as a GATT client, it may follow the procedures
1407 * listed below.
1408 * 1. Create connection with the unprovisioned device
1409 * 2. Exchange MTU size
1410 * 3. Find Mesh Prov Service in the device's service database
1411 * 4. Find Mesh Prov Data In/Out characteristic within the service
1412 * 5. Get CCC of Mesh Prov Data Out Characteristic
1413 * 6. Set the Notification bit of CCC
1414 */
1415
bt_mesh_gattc_conn_create(const bt_mesh_addr_t * addr,uint16_t service_uuid)1416 int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
1417 {
1418 uint8_t zero[6] = {0};
1419 int i, rc;
1420
1421 if (!addr || !memcmp(addr->val, zero, BLE_MESH_ADDR_LEN) ||
1422 (addr->type > BLE_ADDR_RANDOM)) {
1423 BT_ERR("Invalid remote address");
1424 return -EINVAL;
1425 }
1426
1427 if (service_uuid != BLE_MESH_UUID_MESH_PROV_VAL &&
1428 service_uuid != BLE_MESH_UUID_MESH_PROXY_VAL) {
1429 BT_ERR("Invalid service uuid 0x%04x", service_uuid);
1430 return -EINVAL;
1431 }
1432
1433 /* Check if already creating connection with the device */
1434 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1435 if (!memcmp(bt_mesh_gattc_info[i].addr.val, addr->val, BLE_MESH_ADDR_LEN)) {
1436 BT_WARN("Already create connection with %s",
1437 bt_hex(addr->val, BLE_MESH_ADDR_LEN));
1438 return -EALREADY;
1439 }
1440 }
1441
1442 /* Find empty element in queue to store device info */
1443 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1444 if ((bt_mesh_gattc_info[i].conn.handle == 0xFFFF) &&
1445 (bt_mesh_gattc_info[i].service_uuid == 0x0000)) {
1446 memcpy(bt_mesh_gattc_info[i].addr.val, addr->val, BLE_MESH_ADDR_LEN);
1447 bt_mesh_gattc_info[i].addr.type = addr->type;
1448 /* Service to be found after exchanging mtu size */
1449 bt_mesh_gattc_info[i].service_uuid = service_uuid;
1450 break;
1451 }
1452 }
1453
1454 if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
1455 BT_WARN("gattc info is full");
1456 return -ENOMEM;
1457 }
1458
1459 if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
1460 rc = ble_gap_disc_cancel();
1461 if (rc != 0) {
1462 return -1;
1463 }
1464 bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
1465 }
1466
1467 BT_DBG("Create conn with %s", bt_hex(addr->val, BLE_MESH_ADDR_LEN));
1468
1469 /* Min_interval: 15ms
1470 * Max_interval: 15ms
1471 * Slave_latency: 0x0
1472 * Supervision_timeout: 1s
1473 */
1474 struct ble_gap_conn_params conn_params = {0};
1475 conn_params.itvl_min = 0x18;
1476 conn_params.itvl_max = 0x18;
1477 conn_params.latency = 0;
1478 conn_params.supervision_timeout = 0x64;
1479 conn_params.scan_itvl = 0x0020;
1480 conn_params.scan_window = 0x0020;
1481 conn_params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN;
1482 conn_params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN;
1483
1484
1485 ble_addr_t peer_addr;
1486 memcpy(peer_addr.val, addr->val, 6);
1487 peer_addr.type = addr->type;
1488
1489 return ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER, &conn_params,
1490 disc_cb, NULL);
1491 }
1492
mtu_cb(uint16_t conn_handle,const struct ble_gatt_error * error,uint16_t mtu,void * arg)1493 static int mtu_cb(uint16_t conn_handle,
1494 const struct ble_gatt_error *error,
1495 uint16_t mtu, void *arg)
1496 {
1497 int i;
1498 if (error->status == 0) {
1499
1500 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1501 if (bt_mesh_gattc_info[i].conn.handle == conn_handle) {
1502 bt_mesh_gattc_info[i].mtu = mtu;
1503 break;
1504 }
1505 }
1506 }
1507 return 0;
1508 }
1509
1510
1511
bt_mesh_gattc_exchange_mtu(uint8_t index)1512 void bt_mesh_gattc_exchange_mtu(uint8_t index)
1513 {
1514 /** Set local MTU and exchange with GATT server.
1515 * ATT_MTU >= 69 for Mesh GATT Prov Service
1516 * ATT_NTU >= 33 for Mesh GATT Proxy Service
1517 */
1518
1519 ble_gattc_exchange_mtu(bt_mesh_gattc_info[index].conn.handle, mtu_cb, NULL);
1520 }
1521
bt_mesh_gattc_get_mtu_info(struct bt_mesh_conn * conn)1522 uint16_t bt_mesh_gattc_get_mtu_info(struct bt_mesh_conn *conn)
1523 {
1524 int i;
1525
1526 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1527 if (conn == &bt_mesh_gattc_info[i].conn) {
1528 return bt_mesh_gattc_info[i].mtu;
1529 }
1530 }
1531
1532 return 0;
1533 }
1534
bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,const void * data,uint16_t len)1535 int bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn *conn,
1536 const struct bt_mesh_gatt_attr *attr,
1537 const void *data, uint16_t len)
1538 {
1539 uint16_t conn_id;
1540 int i;
1541
1542 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1543 if (conn == &bt_mesh_gattc_info[i].conn) {
1544 break;
1545 }
1546 }
1547
1548 if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
1549 BT_ERR("Conn %p not found", conn);
1550 /** Here we return 0 for prov_send() return value check in provisioner.c
1551 */
1552 return 0;
1553 }
1554
1555 conn_id = BLE_MESH_GATT_CREATE_CONN_ID(bt_mesh_gattc_info[i].conn.handle);
1556
1557 struct os_mbuf *om;
1558 int rc;
1559
1560 om = ble_hs_mbuf_from_flat(data, len);
1561 if (om == NULL) {
1562 return -1;
1563 }
1564
1565 rc = ble_gattc_write_no_rsp(conn_id, bt_mesh_gattc_info[i].data_in_handle, om);
1566 if (rc != 0) {
1567 return -1;
1568 }
1569
1570 return 0;
1571 }
1572
bt_mesh_gattc_disconnect(struct bt_mesh_conn * conn)1573 void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn)
1574 {
1575 /** Disconnect
1576 * Clear proper proxy server information
1577 * Clear proper prov_link information
1578 * Clear proper bt_mesh_gattc_info information
1579 * Here in adapter, we just clear proper bt_mesh_gattc_info, and
1580 * when proxy_disconnected callback comes, the proxy server
1581 * information and prov_link information should be cleared.
1582 */
1583 int i;
1584
1585 for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1586 if (conn == &bt_mesh_gattc_info[i].conn) {
1587 break;
1588 }
1589 }
1590
1591 if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
1592 BT_ERR("Conn %p not found", conn);
1593 return;
1594 }
1595 ble_gap_terminate(bt_mesh_gattc_info[i].conn.handle, BLE_ERR_REM_USER_CONN_TERM);
1596 }
1597
1598 /** Mesh Provisioning Service: 0x1827
1599 * Mesh Provisioning Data In: 0x2ADB
1600 * Mesh Provisioning Data Out: 0x2ADC
1601 * Mesh Proxy Service: 0x1828
1602 * Mesh Proxy Data In: 0x2ADD
1603 * Mesh PROXY Data Out: 0x2ADE
1604 */
1605 #endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
1606
bt_mesh_conn_ref(struct bt_mesh_conn * conn)1607 struct bt_mesh_conn *bt_mesh_conn_ref(struct bt_mesh_conn *conn)
1608 {
1609 bt_mesh_atomic_inc(&conn->ref);
1610
1611 BT_DBG("handle %u ref %u", conn->handle, bt_mesh_atomic_get(&conn->ref));
1612
1613 return conn;
1614 }
1615
bt_mesh_conn_unref(struct bt_mesh_conn * conn)1616 void bt_mesh_conn_unref(struct bt_mesh_conn *conn)
1617 {
1618 bt_mesh_atomic_dec(&conn->ref);
1619
1620 BT_DBG("handle %u ref %u", conn->handle, bt_mesh_atomic_get(&conn->ref));
1621 }
1622
1623 #if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE
proxy_char_access_cb(uint16_t conn_handle,uint16_t attr_handle,struct ble_gatt_access_ctxt * ctxt,void * arg)1624 static int proxy_char_access_cb(uint16_t conn_handle, uint16_t attr_handle,
1625 struct ble_gatt_access_ctxt *ctxt, void *arg)
1626 {
1627 if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR || ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) {
1628 struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(attr_handle);
1629 uint8_t index = BLE_MESH_GATT_GET_CONN_ID(conn_handle);
1630 uint16_t len = 0;
1631
1632 BT_DBG("write, handle %d, len %d, data %s", attr_handle,
1633 ctxt->om->om_len,
1634 bt_hex(ctxt->om->om_data, ctxt->om->om_len));
1635
1636 if (attr != NULL && attr->write != NULL) {
1637 if ((len = attr->write(&bt_mesh_gatts_conn[index], attr,
1638 ctxt->om->om_data,
1639 ctxt->om->om_len,
1640 0 /* offset */, 0)) > 0) {
1641 }
1642 }
1643 } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR || ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) {
1644 BT_ERR("Unhandled read request for chr and dsc: opcode - %d", ctxt->op);
1645 }
1646 return 0;
1647 }
1648
dummy_access_cb(uint16_t conn_handle,uint16_t attr_handle,struct ble_gatt_access_ctxt * ctxt,void * arg)1649 static int dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle,
1650 struct ble_gatt_access_ctxt *ctxt, void *arg)
1651 {
1652 /*
1653 * We should never never enter this callback - it's attached to notify-only
1654 * characteristic which are notified directly from mbuf. And we can't pass
1655 * NULL as access_cb because gatts will assert on init...
1656 */
1657 assert(0);
1658 return 0;
1659 }
1660
1661 static const struct ble_gatt_svc_def svc_defs [] = {
1662 #ifdef CONFIG_BLE_MESH_GATT_PROXY_SERVER
1663 {
1664 .type = BLE_GATT_SVC_TYPE_PRIMARY,
1665 .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL),
1666 .includes = NULL,
1667 .characteristics = (struct ble_gatt_chr_def[])
1668 { {
1669 .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL),
1670 .access_cb = proxy_char_access_cb,
1671 .flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
1672 }, {
1673 .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL),
1674 .access_cb = dummy_access_cb,
1675 .flags = BLE_GATT_CHR_F_NOTIFY,
1676 }, {
1677 0, /* No more characteristics in this service. */
1678 }
1679 },
1680 },
1681 #endif
1682 #ifdef CONFIG_BLE_MESH_PB_GATT
1683 {
1684 .type = BLE_GATT_SVC_TYPE_PRIMARY,
1685 .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL),
1686 .includes = NULL,
1687 .characteristics = (struct ble_gatt_chr_def[])
1688 { {
1689 .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL),
1690 .access_cb = proxy_char_access_cb,
1691 .flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
1692 }, {
1693 .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL),
1694 .access_cb = dummy_access_cb,
1695 .flags = BLE_GATT_CHR_F_NOTIFY,
1696 }, {
1697 0, /* No more characteristics in this service. */
1698 }
1699 },
1700 },
1701 #endif
1702 {
1703 0, /* No more services. */
1704 },
1705 };
1706 #endif
1707
gatt_register_cb(struct ble_gatt_register_ctxt * ctxt,void * arg)1708 void gatt_register_cb(struct ble_gatt_register_ctxt *ctxt,
1709 void *arg )
1710 {
1711 if (ctxt->op == BLE_GATT_REGISTER_OP_SVC) {
1712 if (ble_uuid_cmp(ctxt->svc.svc_def->uuid, BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL)) == 0) {
1713 proxy_svc_start_handle = ctxt->svc.handle;
1714 } else if (ble_uuid_cmp(ctxt->svc.svc_def->uuid, BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL)) == 0) {
1715 prov_svc_start_handle = ctxt->svc.handle;
1716 }
1717 }
1718 }
1719
bt_mesh_gatt_init(void)1720 void bt_mesh_gatt_init(void)
1721 {
1722 ble_att_set_preferred_mtu(BLE_ATT_MTU_DFLT);
1723
1724 ble_hs_cfg.gatts_register_cb = gatt_register_cb;
1725
1726 #if defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE
1727 static bool init = false;
1728 int rc;
1729
1730 if (init == false) {
1731 ble_svc_gap_init();
1732 ble_svc_gatt_init();
1733
1734 rc = ble_gatts_count_cfg(svc_defs);
1735 assert(rc == 0);
1736
1737 rc = ble_gatts_add_svcs(svc_defs);
1738 assert(rc == 0);
1739
1740 ble_gatts_start();
1741
1742 ble_gatts_svc_set_visibility(prov_svc_start_handle, 1);
1743 ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0);
1744
1745 init = true;
1746 }
1747 #endif
1748
1749 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
1750 CONFIG_BLE_MESH_GATT_PROXY_CLIENT
1751 for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1752 bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
1753 bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT;
1754 bt_mesh_gattc_info[i].wr_desc_done = false;
1755 }
1756 #endif
1757 }
1758
1759 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_gatt_deinit(void)1760 void bt_mesh_gatt_deinit(void)
1761 {
1762 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
1763 CONFIG_BLE_MESH_GATT_PROXY_SERVER
1764 memset(bt_mesh_gatts_addr, 0, BLE_MESH_ADDR_LEN);
1765 #endif
1766
1767 #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
1768 CONFIG_BLE_MESH_GATT_PROXY_CLIENT
1769 for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
1770 bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
1771 memset(&bt_mesh_gattc_info[i].addr, 0, sizeof(bt_mesh_addr_t));
1772 bt_mesh_gattc_info[i].service_uuid = 0U;
1773 bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT;
1774 bt_mesh_gattc_info[i].wr_desc_done = false;
1775 bt_mesh_gattc_info[i].start_handle = 0U;
1776 bt_mesh_gattc_info[i].end_handle = 0U;
1777 bt_mesh_gattc_info[i].data_in_handle = 0U;
1778 bt_mesh_gattc_info[i].data_out_handle = 0U;
1779 bt_mesh_gattc_info[i].ccc_handle = 0U;
1780 }
1781 #endif
1782 }
1783 #endif /* CONFIG_BLE_MESH_DEINIT */
1784
1785 void ble_sm_alg_ecc_init(void);
1786
bt_mesh_adapt_init(void)1787 void bt_mesh_adapt_init(void)
1788 {
1789 BT_DBG("%s", __func__);
1790
1791 /* initialization of P-256 parameters */
1792 ble_sm_alg_ecc_init();
1793
1794 /* Set "bt_mesh_dev.flags" to 0 (only the "BLE_MESH_DEV_HAS_PUB_KEY"
1795 * flag is used) here, because we need to make sure each time after
1796 * the private key is initialized, a corresponding public key must
1797 * be generated.
1798 */
1799 bt_mesh_atomic_set(bt_mesh_dev.flags, 0);
1800 bt_mesh_rand(bt_mesh_private_key, sizeof(bt_mesh_private_key));
1801 }
1802
bt_mesh_set_private_key(const uint8_t pri_key[32])1803 void bt_mesh_set_private_key(const uint8_t pri_key[32])
1804 {
1805 memcpy(bt_mesh_private_key, pri_key, 32);
1806 }
1807
1808 int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv);
1809
bt_mesh_pub_key_get(void)1810 const uint8_t *bt_mesh_pub_key_get(void)
1811 {
1812 uint8_t pri_key[32] = {0};
1813
1814 #if 1
1815 if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_HAS_PUB_KEY)) {
1816 return bt_mesh_public_key;
1817 }
1818 #else
1819 /* BLE Mesh BQB test case MESH/NODE/PROV/UPD/BV-12-C requires
1820 * different public key for each provisioning procedure.
1821 * Note: if enabled, when Provisioner provision multiple devices
1822 * at the same time, this may cause invalid confirmation value.
1823 */
1824 if (bt_mesh_rand(bt_mesh_private_key, 32)) {
1825 BT_ERR("%s, Unable to generate bt_mesh_private_key", __func__);
1826 return NULL;
1827 }
1828 #endif
1829
1830 int rc = ble_sm_alg_gen_key_pair(bt_mesh_public_key, pri_key);
1831 if (rc != 0) {
1832 BT_ERR("Failed to generate the key pair");
1833 return NULL;
1834 }
1835 memcpy(bt_mesh_private_key, pri_key, 32);
1836
1837 bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_HAS_PUB_KEY);
1838
1839 BT_DBG("Public Key %s", bt_hex(bt_mesh_public_key, sizeof(bt_mesh_public_key)));
1840
1841 return bt_mesh_public_key;
1842 }
1843
bt_mesh_check_public_key(const uint8_t key[64])1844 bool bt_mesh_check_public_key(const uint8_t key[64])
1845 {
1846 struct mbedtls_ecp_point pt = {0};
1847 mbedtls_ecp_group grp = {0};
1848 bool rc = false;
1849
1850 uint8_t pub[65] = {0};
1851 /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */
1852 pub[0] = 0x04;
1853 memcpy(&pub[1], key, 64);
1854
1855 /* Initialize the required structures here */
1856 mbedtls_ecp_point_init(&pt);
1857 mbedtls_ecp_group_init(&grp);
1858
1859 /* Below 3 steps are to validate public key on curve secp256r1 */
1860 if (mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1) != 0) {
1861 goto exit;
1862 }
1863
1864 if (mbedtls_ecp_point_read_binary(&grp, &pt, pub, 65) != 0) {
1865 goto exit;
1866 }
1867
1868 if (mbedtls_ecp_check_pubkey(&grp, &pt) != 0) {
1869 goto exit;
1870 }
1871
1872 rc = true;
1873
1874 exit:
1875 mbedtls_ecp_point_free(&pt);
1876 mbedtls_ecp_group_free(&grp);
1877 return rc;
1878
1879 }
1880
1881 int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y,
1882 uint8_t *our_priv_key, uint8_t *out_dhkey);
1883
bt_mesh_dh_key_gen(const uint8_t remote_pk[64],bt_mesh_dh_key_cb_t cb,const uint8_t idx)1884 int bt_mesh_dh_key_gen(const uint8_t remote_pk[64], bt_mesh_dh_key_cb_t cb, const uint8_t idx)
1885 {
1886 uint8_t dhkey[32];
1887
1888 BT_DBG("private key = %s", bt_hex(bt_mesh_private_key, 32));
1889
1890 ble_sm_alg_gen_dhkey((uint8_t *)&remote_pk[0], (uint8_t *)&remote_pk[32], bt_mesh_private_key, dhkey);
1891
1892 if (cb != NULL) {
1893 cb((const uint8_t *)dhkey, idx);
1894 }
1895 return 0;
1896 }
1897
bt_mesh_encrypt_le(const uint8_t key[16],const uint8_t plaintext[16],uint8_t enc_data[16])1898 int bt_mesh_encrypt_le(const uint8_t key[16], const uint8_t plaintext[16],
1899 uint8_t enc_data[16])
1900 {
1901 uint8_t tmp[16] = {0};
1902
1903 BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16));
1904
1905 #if CONFIG_MBEDTLS_HARDWARE_AES
1906 mbedtls_aes_context ctx = {0};
1907
1908 mbedtls_aes_init(&ctx);
1909
1910 sys_memcpy_swap(tmp, key, 16);
1911
1912 if (mbedtls_aes_setkey_enc(&ctx, tmp, 128) != 0) {
1913 mbedtls_aes_free(&ctx);
1914 return -EINVAL;
1915 }
1916
1917 sys_memcpy_swap(tmp, plaintext, 16);
1918
1919 if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT,
1920 tmp, enc_data) != 0) {
1921 mbedtls_aes_free(&ctx);
1922 return -EINVAL;
1923 }
1924
1925 mbedtls_aes_free(&ctx);
1926 #else /* CONFIG_MBEDTLS_HARDWARE_AES */
1927 struct tc_aes_key_sched_struct s = {0};
1928
1929 sys_memcpy_swap(tmp, key, 16);
1930
1931 if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) {
1932 return -EINVAL;
1933 }
1934
1935 sys_memcpy_swap(tmp, plaintext, 16);
1936
1937 if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) {
1938 return -EINVAL;
1939 }
1940 #endif /* CONFIG_MBEDTLS_HARDWARE_AES */
1941
1942 sys_mem_swap(enc_data, 16);
1943
1944 BT_DBG("enc_data %s", bt_hex(enc_data, 16));
1945
1946 return 0;
1947 }
1948
bt_mesh_encrypt_be(const uint8_t key[16],const uint8_t plaintext[16],uint8_t enc_data[16])1949 int bt_mesh_encrypt_be(const uint8_t key[16], const uint8_t plaintext[16],
1950 uint8_t enc_data[16])
1951 {
1952 BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16));
1953
1954 #if CONFIG_MBEDTLS_HARDWARE_AES
1955 mbedtls_aes_context ctx = {0};
1956
1957 mbedtls_aes_init(&ctx);
1958
1959 if (mbedtls_aes_setkey_enc(&ctx, key, 128) != 0) {
1960 mbedtls_aes_free(&ctx);
1961 return -EINVAL;
1962 }
1963
1964 if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT,
1965 plaintext, enc_data) != 0) {
1966 mbedtls_aes_free(&ctx);
1967 return -EINVAL;
1968 }
1969
1970 mbedtls_aes_free(&ctx);
1971 #else /* CONFIG_MBEDTLS_HARDWARE_AES */
1972 struct tc_aes_key_sched_struct s = {0};
1973
1974 if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) {
1975 return -EINVAL;
1976 }
1977
1978 if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) {
1979 return -EINVAL;
1980 }
1981 #endif /* CONFIG_MBEDTLS_HARDWARE_AES */
1982
1983 BT_DBG("enc_data %s", bt_hex(enc_data, 16));
1984
1985 return 0;
1986 }
1987
1988 #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN)
bt_mesh_update_exceptional_list(uint8_t sub_code,uint32_t type,void * info)1989 int bt_mesh_update_exceptional_list(uint8_t sub_code, uint32_t type, void *info)
1990 {
1991 uint8_t value[6] = {0};
1992 int rc = 0;
1993
1994 if ((sub_code > BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN) ||
1995 (sub_code < BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
1996 type > BLE_MESH_EXCEP_LIST_TYPE_MESH_PROXY_ADV) ||
1997 (sub_code == BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
1998 !(type & BLE_MESH_EXCEP_LIST_CLEAN_ALL_LIST))) {
1999 BT_ERR("%s, Invalid parameter", __func__);
2000 return -EINVAL;
2001 }
2002
2003 if (type == BLE_MESH_EXCEP_LIST_TYPE_MESH_LINK_ID) {
2004 if (!info) {
2005 BT_ERR("Invalid Provisioning Link ID");
2006 return -EINVAL;
2007 }
2008
2009 /* When removing an unused link (i.e., Link ID is 0), and since
2010 * Controller has never added this Link ID, it will cause error
2011 * log been wrongly reported.
2012 * Therefore, add this check here to avoid such occurrences.
2013 */
2014 if (*(uint32_t*)info == 0) {
2015 return 0;
2016 }
2017
2018 sys_memcpy_swap(value, info, sizeof(uint32_t));
2019 }
2020
2021 BT_DBG("%s exceptional list, type 0x%08x", sub_code ? "Remove" : "Add", type);
2022
2023 #if MYNEWT_VAL(BLE_HCI_VS)
2024 rc = ble_gap_duplicate_exception_list(sub_code, type, value, NULL);
2025 #endif
2026
2027 return rc;
2028 }
2029 #endif
2030