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