1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 #include <string.h>
10 #include <errno.h>
11 
12 #include "mesh.h"
13 #include "adv.h"
14 #include "prov.h"
15 #include "beacon.h"
16 #include "access.h"
17 #include "transport.h"
18 #include "foundation.h"
19 #include "mesh_common.h"
20 #include "proxy_server.h"
21 
22 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
23     CONFIG_BLE_MESH_GATT_PROXY_SERVER
24 
25 /* Not support enabling Proxy Client and Proxy Server simultaneously */
26 _Static_assert(!(IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)),
27                "Not support Proxy Server and Proxy Client simultaneously");
28 
29 #define PDU_TYPE(data)     (data[0] & BIT_MASK(6))
30 #define PDU_SAR(data)      (data[0] >> 6)
31 
32 /* Mesh Profile 1.0 Section 6.6:
33  * "The timeout for the SAR transfer is 20 seconds. When the timeout
34  *  expires, the Proxy Server shall disconnect."
35  */
36 #define PROXY_SAR_TIMEOUT  K_SECONDS(20)
37 
38 #define SAR_COMPLETE       0x00
39 #define SAR_FIRST          0x01
40 #define SAR_CONT           0x02
41 #define SAR_LAST           0x03
42 
43 #define CFG_FILTER_SET     0x00
44 #define CFG_FILTER_ADD     0x01
45 #define CFG_FILTER_REMOVE  0x02
46 #define CFG_FILTER_STATUS  0x03
47 
48 #define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6)))
49 
50 #define CLIENT_BUF_SIZE 68
51 
52 #define ADV_OPT (BLE_MESH_ADV_OPT_CONNECTABLE | BLE_MESH_ADV_OPT_ONE_TIME)
53 
54 static const struct bt_mesh_adv_param slow_adv_param = {
55     .options = ADV_OPT,
56     .interval_min = BLE_MESH_GAP_ADV_SLOW_INT_MIN,
57     .interval_max = BLE_MESH_GAP_ADV_SLOW_INT_MAX,
58 };
59 
60 static const struct bt_mesh_adv_param fast_adv_param = {
61     .options = ADV_OPT,
62     .interval_min = BLE_MESH_GAP_ADV_FAST_INT_MIN_0,
63     .interval_max = BLE_MESH_GAP_ADV_FAST_INT_MAX_0,
64 };
65 
66 static bool proxy_adv_enabled;
67 
68 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
69 static void proxy_send_beacons(struct k_work *work);
70 static uint16_t proxy_ccc_val;
71 #endif
72 
73 #if defined(CONFIG_BLE_MESH_PB_GATT)
74 static uint16_t prov_ccc_val;
75 static bool prov_fast_adv;
76 #endif
77 
78 static struct bt_mesh_proxy_client {
79     struct bt_mesh_conn *conn;
80 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
81     uint16_t filter[CONFIG_BLE_MESH_PROXY_FILTER_SIZE];
82 #endif
83     enum __packed {
84         NONE,
85         WHITELIST,
86         BLACKLIST,
87         PROV,
88     } filter_type;
89     uint8_t msg_type;
90 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
91     struct k_work send_beacons;
92 #endif
93     struct k_delayed_work sar_timer;
94     struct net_buf_simple buf;
95 } clients[BLE_MESH_MAX_CONN] = {
96     [0 ... (BLE_MESH_MAX_CONN - 1)] = {
97 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
98         .send_beacons = _K_WORK_INITIALIZER(proxy_send_beacons),
99 #endif
100     },
101 };
102 
103 static uint8_t client_buf_data[CLIENT_BUF_SIZE * BLE_MESH_MAX_CONN];
104 
105 /* Track which service is enabled */
106 static enum {
107     MESH_GATT_NONE,
108     MESH_GATT_PROV,
109     MESH_GATT_PROXY,
110 } gatt_svc = MESH_GATT_NONE;
111 
112 static char device_name[DEVICE_NAME_SIZE + 1];
113 
bt_mesh_set_device_name(const char * name)114 int bt_mesh_set_device_name(const char *name)
115 {
116     if (!name) {
117         BT_ERR("%s, Invalid parameter", __func__);
118         return -EINVAL;
119     }
120 
121     if (strlen(name) > DEVICE_NAME_SIZE) {
122         BT_ERR("Too long device name (len %d)", strlen(name));
123         return -EINVAL;
124     }
125 
126     memset(device_name, 0x0, sizeof(device_name));
127     strncpy(device_name, name, DEVICE_NAME_SIZE);
128 
129     return bt_mesh_gatts_set_local_device_name(device_name);
130 }
131 
find_client(struct bt_mesh_conn * conn)132 static struct bt_mesh_proxy_client *find_client(struct bt_mesh_conn *conn)
133 {
134     int i;
135 
136     for (i = 0; i < ARRAY_SIZE(clients); i++) {
137         if (clients[i].conn == conn) {
138             return &clients[i];
139         }
140     }
141 
142     return NULL;
143 }
144 
proxy_sar_timeout(struct k_work * work)145 static void proxy_sar_timeout(struct k_work *work)
146 {
147     struct bt_mesh_proxy_client *client = NULL;
148 
149     BT_WARN("Proxy SAR timeout");
150 
151     client = CONTAINER_OF(work, struct bt_mesh_proxy_client, sar_timer.work);
152     if (!client || !client->conn) {
153         BT_ERR("Invalid proxy client parameter");
154         return;
155     }
156 
157     net_buf_simple_reset(&client->buf);
158     bt_mesh_gatts_disconnect(client->conn, 0x13);
159 }
160 
161 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
162 /* Next subnet in queue to be advertised */
163 static int next_idx;
164 
165 static int proxy_segment_and_send(struct bt_mesh_conn *conn, uint8_t type,
166                                   struct net_buf_simple *msg);
167 
filter_set(struct bt_mesh_proxy_client * client,struct net_buf_simple * buf)168 static int filter_set(struct bt_mesh_proxy_client *client,
169                       struct net_buf_simple *buf)
170 {
171     uint8_t type = 0U;
172 
173     if (buf->len < 1) {
174         BT_WARN("Too short Filter Set message");
175         return -EINVAL;
176     }
177 
178     type = net_buf_simple_pull_u8(buf);
179     BT_INFO("Set filter type 0x%02x", type);
180 
181     switch (type) {
182     case 0x00:
183         (void)memset(client->filter, 0, sizeof(client->filter));
184         client->filter_type = WHITELIST;
185         break;
186     case 0x01:
187         (void)memset(client->filter, 0, sizeof(client->filter));
188         client->filter_type = BLACKLIST;
189         break;
190     default:
191         BT_WARN("Prohibited Filter Type 0x%02x", type);
192         return -EINVAL;
193     }
194 
195     return 0;
196 }
197 
filter_add(struct bt_mesh_proxy_client * client,uint16_t addr)198 static void filter_add(struct bt_mesh_proxy_client *client, uint16_t addr)
199 {
200     int i;
201 
202     BT_DBG("addr 0x%04x", addr);
203 
204     if (addr == BLE_MESH_ADDR_UNASSIGNED) {
205         return;
206     }
207 
208     for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
209         if (client->filter[i] == addr) {
210             return;
211         }
212     }
213 
214     for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
215         if (client->filter[i] == BLE_MESH_ADDR_UNASSIGNED) {
216             client->filter[i] = addr;
217             BT_INFO("Add filter addr 0x%04x", addr);
218             return;
219         }
220     }
221 
222     BT_WARN("Proxy filter is full!");
223 }
224 
filter_remove(struct bt_mesh_proxy_client * client,uint16_t addr)225 static void filter_remove(struct bt_mesh_proxy_client *client, uint16_t addr)
226 {
227     int i;
228 
229     BT_DBG("addr 0x%04x", addr);
230 
231     if (addr == BLE_MESH_ADDR_UNASSIGNED) {
232         return;
233     }
234 
235     for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
236         if (client->filter[i] == addr) {
237             client->filter[i] = BLE_MESH_ADDR_UNASSIGNED;
238             BT_INFO("Remove filter addr 0x%04x", addr);
239             return;
240         }
241     }
242 }
243 
send_filter_status(struct bt_mesh_proxy_client * client,struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)244 static void send_filter_status(struct bt_mesh_proxy_client *client,
245                                struct bt_mesh_net_rx *rx,
246                                struct net_buf_simple *buf)
247 {
248     struct bt_mesh_net_tx tx = {
249         .sub = rx->sub,
250         .ctx = &rx->ctx,
251         .src = bt_mesh_primary_addr(),
252     };
253     uint16_t filter_size = 0U;
254     int i, err = 0;
255 
256     /* Configuration messages always have dst unassigned */
257     tx.ctx->addr = BLE_MESH_ADDR_UNASSIGNED;
258 
259     net_buf_simple_reset(buf);
260     net_buf_simple_reserve(buf, 10);
261 
262     net_buf_simple_add_u8(buf, CFG_FILTER_STATUS);
263 
264     if (client->filter_type == WHITELIST) {
265         net_buf_simple_add_u8(buf, 0x00);
266     } else {
267         net_buf_simple_add_u8(buf, 0x01);
268     }
269 
270     for (filter_size = 0U, i = 0; i < ARRAY_SIZE(client->filter); i++) {
271         if (client->filter[i] != BLE_MESH_ADDR_UNASSIGNED) {
272             filter_size++;
273         }
274     }
275 
276     net_buf_simple_add_be16(buf, filter_size);
277 
278     BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));
279 
280     err = bt_mesh_net_encode(&tx, buf, true);
281     if (err) {
282         BT_ERR("Encoding proxy cfg message failed (err %d)", err);
283         return;
284     }
285 
286     err = proxy_segment_and_send(client->conn, BLE_MESH_PROXY_CONFIG, buf);
287     if (err) {
288         BT_ERR("Failed to send proxy cfg message (err %d)", err);
289     }
290 }
291 
proxy_cfg(struct bt_mesh_proxy_client * client)292 static void proxy_cfg(struct bt_mesh_proxy_client *client)
293 {
294     NET_BUF_SIMPLE_DEFINE(buf, 29);
295     struct bt_mesh_net_rx rx = {0};
296     uint8_t opcode = 0U;
297     int err = 0;
298 
299     if (client->buf.len > 29) {
300         BT_ERR("Too large proxy cfg pdu (len %d)", client->buf.len);
301         return;
302     }
303 
304     err = bt_mesh_net_decode(&client->buf, BLE_MESH_NET_IF_PROXY_CFG,
305                              &rx, &buf);
306     if (err) {
307         BT_ERR("Failed to decode Proxy Configuration (err %d)", err);
308         return;
309     }
310 
311     rx.local_match = 1U;
312 
313     if (bt_mesh_rpl_check(&rx, NULL)) {
314         BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x",
315                 rx.ctx.addr, rx.ctx.recv_dst, rx.seq);
316         return;
317     }
318 
319     /* Remove network headers */
320     net_buf_simple_pull(&buf, BLE_MESH_NET_HDR_LEN);
321 
322     BT_DBG("%u bytes: %s", buf.len, bt_hex(buf.data, buf.len));
323 
324     if (buf.len < 1) {
325         BT_WARN("Too short proxy configuration PDU");
326         return;
327     }
328 
329     opcode = net_buf_simple_pull_u8(&buf);
330     switch (opcode) {
331     case CFG_FILTER_SET:
332         filter_set(client, &buf);
333         send_filter_status(client, &rx, &buf);
334         break;
335     case CFG_FILTER_ADD:
336         while (buf.len >= 2) {
337             uint16_t addr = 0U;
338 
339             addr = net_buf_simple_pull_be16(&buf);
340             filter_add(client, addr);
341         }
342         send_filter_status(client, &rx, &buf);
343         break;
344     case CFG_FILTER_REMOVE:
345         while (buf.len >= 2) {
346             uint16_t addr = 0U;
347 
348             addr = net_buf_simple_pull_be16(&buf);
349             filter_remove(client, addr);
350         }
351         send_filter_status(client, &rx, &buf);
352         break;
353     default:
354         BT_WARN("Unhandled configuration OpCode 0x%02x", opcode);
355         break;
356     }
357 }
358 
beacon_send(struct bt_mesh_conn * conn,struct bt_mesh_subnet * sub)359 static int beacon_send(struct bt_mesh_conn *conn, struct bt_mesh_subnet *sub)
360 {
361     NET_BUF_SIMPLE_DEFINE(buf, 23);
362 
363     net_buf_simple_reserve(&buf, 1);
364     bt_mesh_beacon_create(sub, &buf);
365 
366     return proxy_segment_and_send(conn, BLE_MESH_PROXY_BEACON, &buf);
367 }
368 
proxy_send_beacons(struct k_work * work)369 static void proxy_send_beacons(struct k_work *work)
370 {
371     struct bt_mesh_proxy_client *client = NULL;
372     int i;
373 
374     client = CONTAINER_OF(work, struct bt_mesh_proxy_client, send_beacons);
375 
376     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
377         struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
378 
379         if (sub->net_idx != BLE_MESH_KEY_UNUSED) {
380             beacon_send(client->conn, sub);
381         }
382     }
383 }
384 
bt_mesh_proxy_server_beacon_send(struct bt_mesh_subnet * sub)385 void bt_mesh_proxy_server_beacon_send(struct bt_mesh_subnet *sub)
386 {
387     int i;
388 
389     if (!sub) {
390         /* NULL means we send on all subnets */
391         for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
392             if (bt_mesh.sub[i].net_idx != BLE_MESH_KEY_UNUSED) {
393                 bt_mesh_proxy_server_beacon_send(&bt_mesh.sub[i]);
394             }
395         }
396 
397         return;
398     }
399 
400     for (i = 0; i < ARRAY_SIZE(clients); i++) {
401         if (clients[i].conn) {
402             beacon_send(clients[i].conn, sub);
403         }
404     }
405 }
406 
bt_mesh_proxy_server_identity_start(struct bt_mesh_subnet * sub)407 void bt_mesh_proxy_server_identity_start(struct bt_mesh_subnet *sub)
408 {
409     sub->node_id = BLE_MESH_NODE_IDENTITY_RUNNING;
410     sub->node_id_start = k_uptime_get_32();
411 
412     /* Prioritize the recently enabled subnet */
413     next_idx = sub - bt_mesh.sub;
414 }
415 
bt_mesh_proxy_server_identity_stop(struct bt_mesh_subnet * sub)416 void bt_mesh_proxy_server_identity_stop(struct bt_mesh_subnet *sub)
417 {
418     sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED;
419     sub->node_id_start = 0U;
420 }
421 
bt_mesh_proxy_identity_enable(void)422 int bt_mesh_proxy_identity_enable(void)
423 {
424     int i, count = 0;
425 
426     BT_DBG("%s", __func__);
427 
428     if (!bt_mesh_is_provisioned()) {
429         return -EAGAIN;
430     }
431 
432     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
433         struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
434 
435         if (sub->net_idx == BLE_MESH_KEY_UNUSED) {
436             continue;
437         }
438 
439         if (sub->node_id == BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED) {
440             continue;
441         }
442 
443         bt_mesh_proxy_server_identity_start(sub);
444         count++;
445     }
446 
447     if (count) {
448         bt_mesh_adv_update();
449     }
450 
451     return 0;
452 }
453 
454 #endif /* GATT_PROXY */
455 
proxy_complete_pdu(struct bt_mesh_proxy_client * client)456 static void proxy_complete_pdu(struct bt_mesh_proxy_client *client)
457 {
458     switch (client->msg_type) {
459 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
460     case BLE_MESH_PROXY_NET_PDU:
461         BT_DBG("Mesh Network PDU");
462         bt_mesh_net_recv(&client->buf, 0, BLE_MESH_NET_IF_PROXY);
463         break;
464     case BLE_MESH_PROXY_BEACON:
465         BT_DBG("Mesh Beacon PDU");
466         bt_mesh_beacon_recv(&client->buf, 0);
467         break;
468     case BLE_MESH_PROXY_CONFIG:
469         BT_DBG("Mesh Configuration PDU");
470         proxy_cfg(client);
471         break;
472 #endif
473 #if defined(CONFIG_BLE_MESH_PB_GATT)
474     case BLE_MESH_PROXY_PROV:
475         BT_DBG("Mesh Provisioning PDU");
476         bt_mesh_pb_gatt_recv(client->conn, &client->buf);
477         break;
478 #endif
479     default:
480         BT_WARN("Unhandled Message Type 0x%02x", client->msg_type);
481         break;
482     }
483 
484     net_buf_simple_reset(&client->buf);
485 }
486 
487 #define ATTR_IS_PROV(attr) (attr->user_data != NULL)
488 
proxy_recv(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)489 static ssize_t proxy_recv(struct bt_mesh_conn *conn,
490                           const struct bt_mesh_gatt_attr *attr, const void *buf,
491                           uint16_t len, uint16_t offset, uint8_t flags)
492 {
493     struct bt_mesh_proxy_client *client = find_client(conn);
494     const uint8_t *data = buf;
495 
496     if (!client) {
497         return -ENOTCONN;
498     }
499 
500     if (len < 1) {
501         BT_WARN("Too small Proxy PDU");
502         return -EINVAL;
503     }
504 
505     if (ATTR_IS_PROV(attr) != (PDU_TYPE(data) == BLE_MESH_PROXY_PROV)) {
506         BT_WARN("Proxy PDU type doesn't match GATT service");
507         return -EINVAL;
508     }
509 
510     if (len - 1 > net_buf_simple_tailroom(&client->buf)) {
511         BT_WARN("Too big proxy PDU");
512         return -EINVAL;
513     }
514 
515     switch (PDU_SAR(data)) {
516     case SAR_COMPLETE:
517         if (client->buf.len) {
518             BT_WARN("Complete PDU while a pending incomplete one");
519             return -EINVAL;
520         }
521 
522         client->msg_type = PDU_TYPE(data);
523         net_buf_simple_add_mem(&client->buf, data + 1, len - 1);
524         proxy_complete_pdu(client);
525         break;
526 
527     case SAR_FIRST:
528         if (client->buf.len) {
529             BT_WARN("First PDU while a pending incomplete one");
530             return -EINVAL;
531         }
532 
533         k_delayed_work_submit(&client->sar_timer, PROXY_SAR_TIMEOUT);
534         client->msg_type = PDU_TYPE(data);
535         net_buf_simple_add_mem(&client->buf, data + 1, len - 1);
536         break;
537 
538     case SAR_CONT:
539         if (!client->buf.len) {
540             BT_WARN("Continuation with no prior data");
541             return -EINVAL;
542         }
543 
544         if (client->msg_type != PDU_TYPE(data)) {
545             BT_WARN("Unexpected message type in continuation");
546             return -EINVAL;
547         }
548 
549         k_delayed_work_submit(&client->sar_timer, PROXY_SAR_TIMEOUT);
550         net_buf_simple_add_mem(&client->buf, data + 1, len - 1);
551         break;
552 
553     case SAR_LAST:
554         if (!client->buf.len) {
555             BT_WARN("Last SAR PDU with no prior data");
556             return -EINVAL;
557         }
558 
559         if (client->msg_type != PDU_TYPE(data)) {
560             BT_WARN("Unexpected message type in last SAR PDU");
561             return -EINVAL;
562         }
563 
564         k_delayed_work_cancel(&client->sar_timer);
565         net_buf_simple_add_mem(&client->buf, data + 1, len - 1);
566         proxy_complete_pdu(client);
567         break;
568     }
569 
570     return len;
571 }
572 
573 static int conn_count;
574 
proxy_connected(struct bt_mesh_conn * conn,uint8_t err)575 static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err)
576 {
577     struct bt_mesh_proxy_client *client = NULL;
578     int i;
579 
580     BT_DBG("conn %p err 0x%02x", conn, err);
581 
582     conn_count++;
583 
584     /* Since we use ADV_OPT_ONE_TIME */
585     proxy_adv_enabled = false;
586 
587     /* Try to re-enable advertising in case it's possible */
588     if (conn_count < BLE_MESH_MAX_CONN) {
589         bt_mesh_adv_update();
590     }
591 
592     for (client = NULL, i = 0; i < ARRAY_SIZE(clients); i++) {
593         if (!clients[i].conn) {
594             client = &clients[i];
595             break;
596         }
597     }
598 
599     if (!client) {
600         BT_ERR("No free Proxy Client objects");
601         return;
602     }
603 
604     client->conn = bt_mesh_conn_ref(conn);
605     client->filter_type = NONE;
606 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
607     (void)memset(client->filter, 0, sizeof(client->filter));
608 #endif
609     net_buf_simple_reset(&client->buf);
610 }
611 
proxy_disconnected(struct bt_mesh_conn * conn,uint8_t reason)612 static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason)
613 {
614     int i;
615 
616     BT_DBG("conn %p reason 0x%02x", conn, reason);
617 
618     conn_count--;
619 
620     for (i = 0; i < ARRAY_SIZE(clients); i++) {
621         struct bt_mesh_proxy_client *client = &clients[i];
622 
623         if (client->conn == conn) {
624             if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
625                     client->filter_type == PROV) {
626                 bt_mesh_pb_gatt_close(conn);
627             }
628 
629             k_delayed_work_cancel(&client->sar_timer);
630             bt_mesh_conn_unref(client->conn);
631             client->conn = NULL;
632             break;
633         }
634     }
635 
636     bt_mesh_adv_update();
637 }
638 
bt_mesh_proxy_server_get_buf(void)639 struct net_buf_simple *bt_mesh_proxy_server_get_buf(void)
640 {
641     struct net_buf_simple *buf = &clients[0].buf;
642 
643     net_buf_simple_reset(buf);
644 
645     return buf;
646 }
647 
648 #if defined(CONFIG_BLE_MESH_PB_GATT)
prov_ccc_write(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)649 static ssize_t prov_ccc_write(struct bt_mesh_conn *conn,
650                               const struct bt_mesh_gatt_attr *attr,
651                               const void *buf, uint16_t len,
652                               uint16_t offset, uint8_t flags)
653 {
654     struct bt_mesh_proxy_client *client = NULL;
655     uint16_t *value = attr->user_data;
656 
657     BT_DBG("len %u: %s", len, bt_hex(buf, len));
658 
659     if (len != sizeof(*value)) {
660         return BLE_MESH_GATT_ERR(BLE_MESH_ATT_ERR_INVALID_ATTRIBUTE_LEN);
661     }
662 
663     *value = sys_get_le16(buf);
664     if (*value != BLE_MESH_GATT_CCC_NOTIFY) {
665         BT_WARN("Client wrote 0x%04x instead enabling notify", *value);
666         return len;
667     }
668 
669     /* If a connection exists there must be a client */
670     client = find_client(conn);
671     if (!client) {
672         BT_ERR("No client for connection %p", conn);
673         return 0;
674     }
675 
676     if (client->filter_type == NONE) {
677         client->filter_type = PROV;
678         bt_mesh_pb_gatt_open(conn);
679     }
680 
681     return len;
682 }
683 
prov_ccc_read(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)684 static ssize_t prov_ccc_read(struct bt_mesh_conn *conn,
685                              const struct bt_mesh_gatt_attr *attr,
686                              void *buf, uint16_t len, uint16_t offset)
687 {
688     uint16_t *value = attr->user_data;
689 
690     return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, value,
691                                    sizeof(*value));
692 }
693 
694 /* Mesh Provisioning Service Declaration */
695 static struct bt_mesh_gatt_attr prov_attrs[] = {
696     BLE_MESH_GATT_PRIMARY_SERVICE(BLE_MESH_UUID_MESH_PROV),
697 
698     BLE_MESH_GATT_CHARACTERISTIC(BLE_MESH_UUID_MESH_PROV_DATA_IN,
699     BLE_MESH_GATT_CHRC_WRITE_WITHOUT_RESP),
700     BLE_MESH_GATT_DESCRIPTOR(BLE_MESH_UUID_MESH_PROV_DATA_IN, BLE_MESH_GATT_PERM_WRITE,
701     NULL, proxy_recv, (void *)1),
702 
703     BLE_MESH_GATT_CHARACTERISTIC(BLE_MESH_UUID_MESH_PROV_DATA_OUT,
704     BLE_MESH_GATT_CHRC_NOTIFY),
705     BLE_MESH_GATT_DESCRIPTOR(BLE_MESH_UUID_MESH_PROV_DATA_OUT, BLE_MESH_GATT_PERM_NONE,
706     NULL, NULL, NULL),
707     /* Add custom CCC as clients need to be tracked individually */
708     BLE_MESH_GATT_DESCRIPTOR(BLE_MESH_UUID_GATT_CCC,
709     BLE_MESH_GATT_PERM_WRITE | BLE_MESH_GATT_PERM_READ,
710     prov_ccc_read, prov_ccc_write, &prov_ccc_val),
711 };
712 
713 struct bt_mesh_gatt_service prov_svc = BLE_MESH_GATT_SERVICE(prov_attrs);
714 
bt_mesh_proxy_server_prov_enable(void)715 int bt_mesh_proxy_server_prov_enable(void)
716 {
717     int i;
718 
719     BT_DBG("%s", __func__);
720 
721     if (gatt_svc == MESH_GATT_PROV) {
722         BT_WARN("%s, Already", __func__);
723         return -EALREADY;
724     }
725 
726     if (gatt_svc != MESH_GATT_NONE) {
727         BT_WARN("%s, Busy", __func__);
728         return -EBUSY;
729     }
730 
731     bt_mesh_gatts_service_start(&prov_svc);
732     gatt_svc = MESH_GATT_PROV;
733     prov_fast_adv = true;
734 
735     for (i = 0; i < ARRAY_SIZE(clients); i++) {
736         if (clients[i].conn) {
737             clients[i].filter_type = PROV;
738         }
739     }
740 
741 
742     return 0;
743 }
744 
bt_mesh_proxy_server_prov_disable(bool disconnect)745 int bt_mesh_proxy_server_prov_disable(bool disconnect)
746 {
747     int i;
748 
749     BT_DBG("%s", __func__);
750 
751     if (gatt_svc == MESH_GATT_NONE) {
752         BT_WARN("%s, Already", __func__);
753         return -EALREADY;
754     }
755 
756     if (gatt_svc != MESH_GATT_PROV) {
757         BT_WARN("%s, Busy", __func__);
758         return -EBUSY;
759     }
760 
761     bt_mesh_gatts_service_stop(&prov_svc);
762     gatt_svc = MESH_GATT_NONE;
763 
764     for (i = 0; i < ARRAY_SIZE(clients); i++) {
765         struct bt_mesh_proxy_client *client = &clients[i];
766 
767         if (!client->conn || client->filter_type != PROV) {
768             continue;
769         }
770 
771         if (disconnect) {
772             bt_mesh_gatts_disconnect(client->conn, 0x13);
773         } else {
774             bt_mesh_pb_gatt_close(client->conn);
775             client->filter_type = NONE;
776         }
777     }
778 
779     bt_mesh_adv_update();
780 
781     return 0;
782 }
783 
784 #endif /* CONFIG_BLE_MESH_PB_GATT */
785 
786 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
proxy_ccc_write(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)787 static ssize_t proxy_ccc_write(struct bt_mesh_conn *conn,
788                                const struct bt_mesh_gatt_attr *attr,
789                                const void *buf, uint16_t len,
790                                uint16_t offset, uint8_t flags)
791 {
792     struct bt_mesh_proxy_client *client = NULL;
793     uint16_t value = 0U;
794 
795     BT_DBG("len %u: %s", len, bt_hex(buf, len));
796 
797     if (len != sizeof(value)) {
798         return BLE_MESH_GATT_ERR(BLE_MESH_ATT_ERR_INVALID_ATTRIBUTE_LEN);
799     }
800 
801     value = sys_get_le16(buf);
802     if (value != BLE_MESH_GATT_CCC_NOTIFY) {
803         BT_WARN("Client wrote 0x%04x instead enabling notify", value);
804         return len;
805     }
806 
807     /* If a connection exists there must be a client */
808     client = find_client(conn);
809     if (!client) {
810         BT_ERR("No client for connection %p", conn);
811         return 0;
812     }
813 
814     if (client->filter_type == NONE) {
815         client->filter_type = WHITELIST;
816         k_work_submit(&client->send_beacons);
817     }
818 
819     return len;
820 }
821 
proxy_ccc_read(struct bt_mesh_conn * conn,const struct bt_mesh_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)822 static ssize_t proxy_ccc_read(struct bt_mesh_conn *conn,
823                               const struct bt_mesh_gatt_attr *attr,
824                               void *buf, uint16_t len, uint16_t offset)
825 {
826     uint16_t *value = attr->user_data;
827 
828     return bt_mesh_gatts_attr_read(conn, attr, buf, len, offset, value,
829                                    sizeof(*value));
830 }
831 
832 /* Mesh Proxy Service Declaration */
833 static struct bt_mesh_gatt_attr proxy_attrs[] = {
834     BLE_MESH_GATT_PRIMARY_SERVICE(BLE_MESH_UUID_MESH_PROXY),
835 
836     BLE_MESH_GATT_CHARACTERISTIC(BLE_MESH_UUID_MESH_PROXY_DATA_IN,
837     BLE_MESH_GATT_CHRC_WRITE_WITHOUT_RESP),
838     BLE_MESH_GATT_DESCRIPTOR(BLE_MESH_UUID_MESH_PROXY_DATA_IN, BLE_MESH_GATT_PERM_WRITE,
839     NULL, proxy_recv, NULL),
840 
841     BLE_MESH_GATT_CHARACTERISTIC(BLE_MESH_UUID_MESH_PROXY_DATA_OUT,
842     BLE_MESH_GATT_CHRC_NOTIFY),
843     BLE_MESH_GATT_DESCRIPTOR(BLE_MESH_UUID_MESH_PROXY_DATA_OUT, BLE_MESH_GATT_PERM_NONE,
844     NULL, NULL, NULL),
845     /* Add custom CCC as clients need to be tracked individually */
846     BLE_MESH_GATT_DESCRIPTOR(BLE_MESH_UUID_GATT_CCC,
847     BLE_MESH_GATT_PERM_READ | BLE_MESH_GATT_PERM_WRITE,
848     proxy_ccc_read, proxy_ccc_write, &proxy_ccc_val),
849 };
850 
851 struct bt_mesh_gatt_service proxy_svc = BLE_MESH_GATT_SERVICE(proxy_attrs);
852 
bt_mesh_proxy_server_gatt_enable(void)853 int bt_mesh_proxy_server_gatt_enable(void)
854 {
855     int i;
856 
857     BT_DBG("%s", __func__);
858 
859     if (gatt_svc == MESH_GATT_PROXY) {
860         BT_WARN("%s, Already", __func__);
861         return -EALREADY;
862     }
863 
864     if (gatt_svc != MESH_GATT_NONE) {
865         BT_WARN("%s, Busy", __func__);
866         return -EBUSY;
867     }
868 
869     bt_mesh_gatts_service_start(&proxy_svc);
870     gatt_svc = MESH_GATT_PROXY;
871 
872     for (i = 0; i < ARRAY_SIZE(clients); i++) {
873         if (clients[i].conn) {
874             clients[i].filter_type = WHITELIST;
875         }
876     }
877 
878     return 0;
879 }
880 
bt_mesh_proxy_server_gatt_disconnect(void)881 void bt_mesh_proxy_server_gatt_disconnect(void)
882 {
883     int i;
884 
885     BT_DBG("%s", __func__);
886 
887     for (i = 0; i < ARRAY_SIZE(clients); i++) {
888         struct bt_mesh_proxy_client *client = &clients[i];
889 
890         if (client->conn && (client->filter_type == WHITELIST ||
891                              client->filter_type == BLACKLIST)) {
892             client->filter_type = NONE;
893             bt_mesh_gatts_disconnect(client->conn, 0x13);
894         }
895     }
896 }
897 
bt_mesh_proxy_server_gatt_disable(void)898 int bt_mesh_proxy_server_gatt_disable(void)
899 {
900     BT_DBG("%s", __func__);
901 
902     if (gatt_svc == MESH_GATT_NONE) {
903         BT_WARN("%s, Already", __func__);
904         return -EALREADY;
905     }
906 
907     if (gatt_svc != MESH_GATT_PROXY) {
908         BT_WARN("%s, Busy", __func__);
909         return -EBUSY;
910     }
911 
912     bt_mesh_proxy_server_gatt_disconnect();
913 
914     bt_mesh_gatts_service_stop(&proxy_svc);
915     gatt_svc = MESH_GATT_NONE;
916 
917     return 0;
918 }
919 
bt_mesh_proxy_server_addr_add(struct net_buf_simple * buf,uint16_t addr)920 void bt_mesh_proxy_server_addr_add(struct net_buf_simple *buf, uint16_t addr)
921 {
922     struct bt_mesh_proxy_client *client =
923         CONTAINER_OF(buf, struct bt_mesh_proxy_client, buf);
924 
925     BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr);
926 
927     if (client->filter_type == WHITELIST) {
928         filter_add(client, addr);
929     } else if (client->filter_type == BLACKLIST) {
930         filter_remove(client, addr);
931     }
932 }
933 
client_filter_match(struct bt_mesh_proxy_client * client,uint16_t addr)934 static bool client_filter_match(struct bt_mesh_proxy_client *client,
935                                 uint16_t addr)
936 {
937     int i;
938 
939     BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr);
940 
941     if (client->filter_type == BLACKLIST) {
942         for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
943             if (client->filter[i] == addr) {
944                 return false;
945             }
946         }
947 
948         return true;
949     }
950 
951     if (addr == BLE_MESH_ADDR_ALL_NODES) {
952         return true;
953     }
954 
955     if (client->filter_type == WHITELIST) {
956         for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
957             if (client->filter[i] == addr) {
958                 return true;
959             }
960         }
961     }
962 
963     return false;
964 }
965 
bt_mesh_proxy_server_relay(struct net_buf_simple * buf,uint16_t dst)966 bool bt_mesh_proxy_server_relay(struct net_buf_simple *buf, uint16_t dst)
967 {
968     bool relayed = false;
969     int i;
970 
971     BT_DBG("%u bytes to dst 0x%04x", buf->len, dst);
972 
973     for (i = 0; i < ARRAY_SIZE(clients); i++) {
974         struct bt_mesh_proxy_client *client = &clients[i];
975         NET_BUF_SIMPLE_DEFINE(msg, 32);
976 
977         if (!client->conn) {
978             continue;
979         }
980 
981         if (!client_filter_match(client, dst)) {
982             continue;
983         }
984 
985         /* Proxy PDU sending modifies the original buffer,
986          * so we need to make a copy.
987          */
988         net_buf_simple_reserve(&msg, 1);
989         net_buf_simple_add_mem(&msg, buf->data, buf->len);
990 
991         bt_mesh_proxy_server_send(client->conn, BLE_MESH_PROXY_NET_PDU, &msg);
992         relayed = true;
993     }
994 
995     return relayed;
996 }
997 
998 #endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */
999 
proxy_send(struct bt_mesh_conn * conn,const void * data,uint16_t len)1000 static int proxy_send(struct bt_mesh_conn *conn, const void *data, uint16_t len)
1001 {
1002     BT_DBG("%u bytes: %s", len, bt_hex(data, len));
1003 
1004 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
1005     if (gatt_svc == MESH_GATT_PROXY) {
1006         return bt_mesh_gatts_notify(conn, &proxy_attrs[4], data, len);
1007     }
1008 #endif
1009 
1010 #if defined(CONFIG_BLE_MESH_PB_GATT)
1011     if (gatt_svc == MESH_GATT_PROV) {
1012         return bt_mesh_gatts_notify(conn, &prov_attrs[4], data, len);
1013     }
1014 #endif
1015 
1016     return 0;
1017 }
1018 
proxy_segment_and_send(struct bt_mesh_conn * conn,uint8_t type,struct net_buf_simple * msg)1019 static int proxy_segment_and_send(struct bt_mesh_conn *conn, uint8_t type,
1020                                   struct net_buf_simple *msg)
1021 {
1022     uint16_t mtu = 0U;
1023 
1024     BT_DBG("conn %p type 0x%02x len %u: %s", conn, type, msg->len,
1025            bt_hex(msg->data, msg->len));
1026 
1027     /* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */
1028     mtu = bt_mesh_gatt_get_mtu(conn) - 3;
1029     if (mtu > msg->len) {
1030         net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type));
1031         return proxy_send(conn, msg->data, msg->len);
1032     }
1033 
1034     net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type));
1035     proxy_send(conn, msg->data, mtu);
1036     net_buf_simple_pull(msg, mtu);
1037 
1038     while (msg->len) {
1039         if (msg->len + 1 < mtu) {
1040             net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type));
1041             proxy_send(conn, msg->data, msg->len);
1042             break;
1043         }
1044 
1045         net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type));
1046         proxy_send(conn, msg->data, mtu);
1047         net_buf_simple_pull(msg, mtu);
1048     }
1049 
1050     return 0;
1051 }
1052 
bt_mesh_proxy_server_send(struct bt_mesh_conn * conn,uint8_t type,struct net_buf_simple * msg)1053 int bt_mesh_proxy_server_send(struct bt_mesh_conn *conn, uint8_t type,
1054                               struct net_buf_simple *msg)
1055 {
1056     struct bt_mesh_proxy_client *client = find_client(conn);
1057 
1058     if (!client) {
1059         BT_ERR("No Proxy Client found");
1060         return -ENOTCONN;
1061     }
1062 
1063     if ((client->filter_type == PROV) != (type == BLE_MESH_PROXY_PROV)) {
1064         BT_ERR("Invalid PDU type for Proxy Client");
1065         return -EINVAL;
1066     }
1067 
1068     return proxy_segment_and_send(conn, type, msg);
1069 }
1070 
1071 #if defined(CONFIG_BLE_MESH_PB_GATT)
1072 static uint8_t prov_svc_data[20] = { 0x27, 0x18, };
1073 
1074 static const struct bt_mesh_adv_data prov_ad[] = {
1075     BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_FLAGS, (BLE_MESH_AD_GENERAL | BLE_MESH_AD_NO_BREDR)),
1076     BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x27, 0x18),
1077     BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)),
1078 };
1079 #endif /* PB_GATT */
1080 
1081 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
1082 
1083 #define ID_TYPE_NET  0x00
1084 #define ID_TYPE_NODE 0x01
1085 
1086 #define NODE_ID_LEN  19
1087 #define NET_ID_LEN   11
1088 
1089 #define NODE_ID_TIMEOUT K_SECONDS(CONFIG_BLE_MESH_NODE_ID_TIMEOUT)
1090 
1091 static uint8_t proxy_svc_data[NODE_ID_LEN] = { 0x28, 0x18, };
1092 
1093 static const struct bt_mesh_adv_data node_id_ad[] = {
1094     BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_FLAGS, (BLE_MESH_AD_GENERAL | BLE_MESH_AD_NO_BREDR)),
1095     BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x28, 0x18),
1096     BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, proxy_svc_data, NODE_ID_LEN),
1097 };
1098 
1099 static const struct bt_mesh_adv_data net_id_ad[] = {
1100     BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_FLAGS, (BLE_MESH_AD_GENERAL | BLE_MESH_AD_NO_BREDR)),
1101     BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x28, 0x18),
1102     BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, proxy_svc_data, NET_ID_LEN),
1103 };
1104 
gatt_proxy_adv_create(struct bt_mesh_adv_data * proxy_sd)1105 static size_t gatt_proxy_adv_create(struct bt_mesh_adv_data *proxy_sd)
1106 {
1107     const char *name = device_name;
1108     size_t name_len = strlen(name);
1109     /* One octet for Length, and another octet for AD type */
1110     size_t sd_space = 29;
1111 
1112     if (name_len > sd_space) {
1113         proxy_sd->type = BLE_MESH_DATA_NAME_SHORTENED;
1114         proxy_sd->data_len = sd_space;
1115     } else {
1116         proxy_sd->type = BLE_MESH_DATA_NAME_COMPLETE;
1117         proxy_sd->data_len = name_len;
1118     }
1119 
1120     proxy_sd->data = (const uint8_t *)name;
1121 
1122     return 1;
1123 }
1124 
node_id_adv(struct bt_mesh_subnet * sub)1125 static int node_id_adv(struct bt_mesh_subnet *sub)
1126 {
1127     struct bt_mesh_adv_data proxy_sd = {0};
1128     size_t proxy_sd_len = 0U;
1129     uint8_t tmp[16] = {0};
1130     int err = 0;
1131 
1132     BT_DBG("%s", __func__);
1133 
1134     proxy_svc_data[2] = ID_TYPE_NODE;
1135 
1136     err = bt_mesh_rand(proxy_svc_data + 11, 8);
1137     if (err) {
1138         return err;
1139     }
1140 
1141     (void)memset(tmp, 0, 6);
1142     memcpy(tmp + 6, proxy_svc_data + 11, 8);
1143     sys_put_be16(bt_mesh_primary_addr(), tmp + 14);
1144 
1145     err = bt_mesh_encrypt_be(sub->keys[sub->kr_flag].identity, tmp, tmp);
1146     if (err) {
1147         return err;
1148     }
1149 
1150     memcpy(proxy_svc_data + 3, tmp + 8, 8);
1151     proxy_sd_len = gatt_proxy_adv_create(&proxy_sd);
1152 
1153     err = bt_le_adv_start(&fast_adv_param, node_id_ad,
1154                           ARRAY_SIZE(node_id_ad), &proxy_sd, proxy_sd_len);
1155     if (err) {
1156         BT_WARN("Failed to advertise using Node ID (err %d)", err);
1157         return err;
1158     }
1159 
1160     proxy_adv_enabled = true;
1161 
1162     return 0;
1163 }
1164 
net_id_adv(struct bt_mesh_subnet * sub)1165 static int net_id_adv(struct bt_mesh_subnet *sub)
1166 {
1167     struct bt_mesh_adv_data proxy_sd = {0};
1168     size_t proxy_sd_len = 0U;
1169     int err = 0;
1170 
1171     BT_DBG("%s", __func__);
1172 
1173     proxy_svc_data[2] = ID_TYPE_NET;
1174 
1175     BT_DBG("Advertising with NetId %s",
1176            bt_hex(sub->keys[sub->kr_flag].net_id, 8));
1177 
1178     memcpy(proxy_svc_data + 3, sub->keys[sub->kr_flag].net_id, 8);
1179     proxy_sd_len = gatt_proxy_adv_create(&proxy_sd);
1180 
1181     err = bt_le_adv_start(&slow_adv_param, net_id_ad,
1182                           ARRAY_SIZE(net_id_ad), &proxy_sd, proxy_sd_len);
1183     if (err) {
1184         BT_WARN("Failed to advertise using Network ID (err %d)", err);
1185         return err;
1186     }
1187 
1188     proxy_adv_enabled = true;
1189 
1190     return 0;
1191 }
1192 
advertise_subnet(struct bt_mesh_subnet * sub)1193 static bool advertise_subnet(struct bt_mesh_subnet *sub)
1194 {
1195     if (sub->net_idx == BLE_MESH_KEY_UNUSED) {
1196         return false;
1197     }
1198 
1199     return (sub->node_id == BLE_MESH_NODE_IDENTITY_RUNNING ||
1200             bt_mesh_gatt_proxy_get() != BLE_MESH_GATT_PROXY_NOT_SUPPORTED);
1201 }
1202 
next_sub(void)1203 static struct bt_mesh_subnet *next_sub(void)
1204 {
1205     struct bt_mesh_subnet *sub = NULL;
1206     int i;
1207 
1208     for (i = next_idx; i < ARRAY_SIZE(bt_mesh.sub); i++) {
1209         sub = &bt_mesh.sub[i];
1210         if (advertise_subnet(sub)) {
1211             next_idx = (i + 1) % ARRAY_SIZE(bt_mesh.sub);
1212             return sub;
1213         }
1214     }
1215 
1216     /**
1217      * If among [next_idx, ARRAY_SIZE(bt_mesh.sub)], there is no subnet
1218      * to advertise, then try to start advertising from Primary subnet.
1219      */
1220     for (i = 0; i < next_idx; i++) {
1221         sub = &bt_mesh.sub[i];
1222         if (advertise_subnet(sub)) {
1223             next_idx = (i + 1) % ARRAY_SIZE(bt_mesh.sub);
1224             return sub;
1225         }
1226     }
1227 
1228     return NULL;
1229 }
1230 
sub_count(void)1231 static int sub_count(void)
1232 {
1233     int i, count = 0;
1234 
1235     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
1236         struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
1237 
1238         if (advertise_subnet(sub)) {
1239             count++;
1240         }
1241     }
1242 
1243     return count;
1244 }
1245 
gatt_proxy_advertise(struct bt_mesh_subnet * sub)1246 static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub)
1247 {
1248     int32_t remaining = K_FOREVER;
1249     int subnet_count = 0;
1250 
1251     BT_DBG("%s", __func__);
1252 
1253     if (conn_count == BLE_MESH_MAX_CONN) {
1254         BT_WARN("Connectable advertising deferred (max connections)");
1255         return remaining;
1256     }
1257 
1258     if (!sub) {
1259         BT_WARN("No subnets to advertise on");
1260         return remaining;
1261     }
1262 
1263     if (sub->node_id == BLE_MESH_NODE_IDENTITY_RUNNING) {
1264         uint32_t active = k_uptime_get_32() - sub->node_id_start;
1265 
1266         if (active < NODE_ID_TIMEOUT) {
1267             remaining = NODE_ID_TIMEOUT - active;
1268             BT_DBG("Node ID active for %u ms, %d ms remaining",
1269                    active, remaining);
1270             node_id_adv(sub);
1271         } else {
1272             bt_mesh_proxy_server_identity_stop(sub);
1273             BT_DBG("Node ID stopped");
1274         }
1275     }
1276 
1277     if (sub->node_id == BLE_MESH_NODE_IDENTITY_STOPPED) {
1278         net_id_adv(sub);
1279     }
1280 
1281     subnet_count = sub_count();
1282     BT_DBG("sub_count %u", subnet_count);
1283     if (subnet_count > 1) {
1284         int32_t max_timeout = 0;
1285 
1286         /* We use NODE_ID_TIMEOUT as a starting point since it may
1287          * be less than 60 seconds. Divide this period into at least
1288          * 6 slices, but make sure that a slice is at least one
1289          * second long (to avoid excessive rotation).
1290          */
1291         max_timeout = NODE_ID_TIMEOUT / MAX(subnet_count, 6);
1292         max_timeout = MAX(max_timeout, K_SECONDS(1));
1293 
1294         if (remaining > max_timeout || remaining < 0) {
1295             remaining = max_timeout;
1296         }
1297     }
1298 
1299     BT_DBG("Advertising %d ms for net_idx 0x%04x", remaining, sub->net_idx);
1300 
1301     return remaining;
1302 }
1303 #endif /* GATT_PROXY */
1304 
1305 #if defined(CONFIG_BLE_MESH_PB_GATT)
gatt_prov_adv_create(struct bt_mesh_adv_data prov_sd[2])1306 static size_t gatt_prov_adv_create(struct bt_mesh_adv_data prov_sd[2])
1307 {
1308     const struct bt_mesh_prov *prov = bt_mesh_prov_get();
1309     const char *name = device_name;
1310     size_t name_len = strlen(name);
1311     size_t prov_sd_len = 0U;
1312     size_t sd_space = 31U;
1313 
1314     memcpy(prov_svc_data + 2, prov->uuid, 16);
1315     sys_put_be16(prov->oob_info, prov_svc_data + 18);
1316 
1317     if (prov->uri) {
1318         size_t uri_len = strlen(prov->uri);
1319 
1320         if (uri_len > 29) {
1321             /* There's no way to shorten an URI */
1322             BT_WARN("Too long URI to fit advertising packet");
1323         } else {
1324             prov_sd[0].type = BLE_MESH_DATA_URI;
1325             prov_sd[0].data_len = uri_len;
1326             prov_sd[0].data = (const uint8_t *)prov->uri;
1327             sd_space -= 2 + uri_len;
1328             prov_sd_len++;
1329         }
1330     }
1331 
1332     if (sd_space > 2 && name_len > 0) {
1333         sd_space -= 2;
1334 
1335         if (sd_space < name_len) {
1336             prov_sd[prov_sd_len].type = BLE_MESH_DATA_NAME_SHORTENED;
1337             prov_sd[prov_sd_len].data_len = sd_space;
1338         } else {
1339             prov_sd[prov_sd_len].type = BLE_MESH_DATA_NAME_COMPLETE;
1340             prov_sd[prov_sd_len].data_len = name_len;
1341         }
1342 
1343         prov_sd[prov_sd_len].data = (const uint8_t *)name;
1344         prov_sd_len++;
1345     }
1346 
1347     return prov_sd_len;
1348 }
1349 #endif /* CONFIG_BLE_MESH_PB_GATT */
1350 
bt_mesh_proxy_server_adv_start(void)1351 int32_t bt_mesh_proxy_server_adv_start(void)
1352 {
1353     BT_DBG("%s", __func__);
1354 
1355     if (gatt_svc == MESH_GATT_NONE) {
1356         return K_FOREVER;
1357     }
1358 
1359 #if defined(CONFIG_BLE_MESH_PB_GATT)
1360     if (!bt_mesh_is_provisioned()) {
1361         const struct bt_mesh_adv_param *param;
1362         struct bt_mesh_adv_data prov_sd[2];
1363         size_t prov_sd_len;
1364 
1365         if (prov_fast_adv) {
1366             param = &fast_adv_param;
1367         } else {
1368             param = &slow_adv_param;
1369         }
1370 
1371         prov_sd_len = gatt_prov_adv_create(prov_sd);
1372 
1373         if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad),
1374                             prov_sd, prov_sd_len) == 0) {
1375             proxy_adv_enabled = true;
1376 
1377             /* Advertise 60 seconds using fast interval */
1378             if (prov_fast_adv) {
1379                 prov_fast_adv = false;
1380                 return K_SECONDS(60);
1381             }
1382         }
1383     }
1384 #endif /* PB_GATT */
1385 
1386 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
1387     if (bt_mesh_is_provisioned()) {
1388         return gatt_proxy_advertise(next_sub());
1389     }
1390 #endif /* GATT_PROXY */
1391 
1392     return K_FOREVER;
1393 }
1394 
bt_mesh_proxy_server_adv_stop(void)1395 void bt_mesh_proxy_server_adv_stop(void)
1396 {
1397     int err = 0;
1398 
1399     BT_DBG("adv_enabled %u", proxy_adv_enabled);
1400 
1401     if (!proxy_adv_enabled) {
1402         return;
1403     }
1404 
1405     err = bt_le_adv_stop();
1406     if (err) {
1407         BT_ERR("Failed to stop advertising (err %d)", err);
1408     } else {
1409         proxy_adv_enabled = false;
1410     }
1411 }
1412 
1413 static struct bt_mesh_conn_cb conn_callbacks = {
1414     .connected = proxy_connected,
1415     .disconnected = proxy_disconnected,
1416 };
1417 
bt_mesh_proxy_server_init(void)1418 int bt_mesh_proxy_server_init(void)
1419 {
1420     int i;
1421 
1422 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
1423     bt_mesh_gatts_service_register(&proxy_svc);
1424 #endif
1425 
1426 #if defined(CONFIG_BLE_MESH_PB_GATT)
1427     bt_mesh_gatts_service_register(&prov_svc);
1428 #endif
1429 
1430     /* Initialize the client receive buffers */
1431     for (i = 0; i < ARRAY_SIZE(clients); i++) {
1432         struct bt_mesh_proxy_client *client = &clients[i];
1433 
1434         client->buf.size = CLIENT_BUF_SIZE;
1435         client->buf.__buf = client_buf_data + (i * CLIENT_BUF_SIZE);
1436 
1437         k_delayed_work_init(&client->sar_timer, proxy_sar_timeout);
1438     }
1439 
1440     bt_mesh_gatts_conn_cb_register(&conn_callbacks);
1441 
1442     strncpy(device_name, "ESP-BLE-MESH", DEVICE_NAME_SIZE);
1443     return bt_mesh_gatts_set_local_device_name(device_name);
1444 }
1445 
1446 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_proxy_server_deinit(void)1447 int bt_mesh_proxy_server_deinit(void)
1448 {
1449     int i;
1450 
1451     proxy_adv_enabled = false;
1452     gatt_svc = MESH_GATT_NONE;
1453 
1454 #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
1455     bt_mesh_gatts_service_deregister(&proxy_svc);
1456     next_idx = 0;
1457 #endif
1458 
1459 #if defined(CONFIG_BLE_MESH_PB_GATT)
1460     bt_mesh_gatts_service_deregister(&prov_svc);
1461 #endif
1462 
1463     for (i = 0; i < ARRAY_SIZE(clients); i++) {
1464         struct bt_mesh_proxy_client *client = &clients[i];
1465         k_delayed_work_free(&client->sar_timer);
1466         memset(client, 0, sizeof(struct bt_mesh_proxy_client));
1467     }
1468 
1469     memset(client_buf_data, 0, sizeof(client_buf_data));
1470     memset(device_name, 0, sizeof(device_name));
1471 
1472     bt_mesh_gatts_conn_cb_deregister();
1473     conn_count = 0;
1474 
1475     return 0;
1476 }
1477 #endif /* CONFIG_BLE_MESH_DEINIT */
1478 
1479 #endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
1480