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