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