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