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