1 /* Bluetooth Mesh */
2
3 /*
4 * Copyright (c) 2017 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 #include "syscfg/syscfg.h"
9 #if MYNEWT_VAL(BLE_MESH_PROV) == 1
10
11 #include <errno.h>
12
13 #define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROV))
14 #include "host/ble_hs_log.h"
15
16 #include "mesh/mesh.h"
17 #include "mesh_priv.h"
18
19 #include <tinycrypt/ecc.h>
20
21 #include "crypto.h"
22 #include "atomic.h"
23 #include "adv.h"
24 #include "net.h"
25 #include "access.h"
26 #include "foundation.h"
27 #include "proxy.h"
28 #include "prov.h"
29 #include "testing.h"
30
31 /* 3 transmissions, 20ms interval */
32 #define PROV_XMIT BT_MESH_TRANSMIT(2, 20)
33
34 #define AUTH_METHOD_NO_OOB 0x00
35 #define AUTH_METHOD_STATIC 0x01
36 #define AUTH_METHOD_OUTPUT 0x02
37 #define AUTH_METHOD_INPUT 0x03
38
39 #define OUTPUT_OOB_BLINK 0x00
40 #define OUTPUT_OOB_BEEP 0x01
41 #define OUTPUT_OOB_VIBRATE 0x02
42 #define OUTPUT_OOB_NUMBER 0x03
43 #define OUTPUT_OOB_STRING 0x04
44
45 #define INPUT_OOB_PUSH 0x00
46 #define INPUT_OOB_TWIST 0x01
47 #define INPUT_OOB_NUMBER 0x02
48 #define INPUT_OOB_STRING 0x03
49
50 #define PROV_ERR_NONE 0x00
51 #define PROV_ERR_NVAL_PDU 0x01
52 #define PROV_ERR_NVAL_FMT 0x02
53 #define PROV_ERR_UNEXP_PDU 0x03
54 #define PROV_ERR_CFM_FAILED 0x04
55 #define PROV_ERR_RESOURCES 0x05
56 #define PROV_ERR_DECRYPT 0x06
57 #define PROV_ERR_UNEXP_ERR 0x07
58 #define PROV_ERR_ADDR 0x08
59
60 #define PROV_INVITE 0x00
61 #define PROV_CAPABILITIES 0x01
62 #define PROV_START 0x02
63 #define PROV_PUB_KEY 0x03
64 #define PROV_INPUT_COMPLETE 0x04
65 #define PROV_CONFIRM 0x05
66 #define PROV_RANDOM 0x06
67 #define PROV_DATA 0x07
68 #define PROV_COMPLETE 0x08
69 #define PROV_FAILED 0x09
70
71 #define PROV_ALG_P256 0x00
72
73 #define GPCF(gpc) (gpc & 0x03)
74 #define GPC_START(last_seg) (((last_seg) << 2) | 0x00)
75 #define GPC_ACK 0x01
76 #define GPC_CONT(seg_id) (((seg_id) << 2) | 0x02)
77 #define GPC_CTL(op) (((op) << 2) | 0x03)
78
79 #define START_PAYLOAD_MAX 20
80 #define CONT_PAYLOAD_MAX 23
81
82 #define START_LAST_SEG(gpc) (gpc >> 2)
83 #define CONT_SEG_INDEX(gpc) (gpc >> 2)
84
85 #define BEARER_CTL(gpc) (gpc >> 2)
86 #define LINK_OPEN 0x00
87 #define LINK_ACK 0x01
88 #define LINK_CLOSE 0x02
89
90 #define CLOSE_REASON_SUCCESS 0x00
91 #define CLOSE_REASON_TIMEOUT 0x01
92 #define CLOSE_REASON_FAILED 0x02
93
94 #define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[20 + ((_seg - 1) * 23)])
95 #define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg)))
96
97 #define XACT_NVAL 0xff
98
99 enum {
100 REMOTE_PUB_KEY, /* Remote key has been received */
101 LOCAL_PUB_KEY, /* Local public key is available */
102 LINK_ACTIVE, /* Link has been opened */
103 HAVE_DHKEY, /* DHKey has been calcualted */
104 SEND_CONFIRM, /* Waiting to send Confirm value */
105 WAIT_NUMBER, /* Waiting for number input from user */
106 WAIT_STRING, /* Waiting for string input from user */
107
108 NUM_FLAGS,
109 };
110
111 struct prov_link {
112 ATOMIC_DEFINE(flags, NUM_FLAGS);
113 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
114 uint16_t conn_handle; /* GATT connection */
115 #endif
116 u8_t dhkey[32]; /* Calculated DHKey */
117 u8_t expect; /* Next expected PDU */
118
119 u8_t oob_method;
120 u8_t oob_action;
121 u8_t oob_size;
122
123 u8_t conf[16]; /* Remote Confirmation */
124 u8_t rand[16]; /* Local Random */
125 u8_t auth[16]; /* Authentication Value */
126
127 u8_t conf_salt[16]; /* ConfirmationSalt */
128 u8_t conf_key[16]; /* ConfirmationKey */
129 u8_t conf_inputs[145]; /* ConfirmationInputs */
130 u8_t prov_salt[16]; /* Provisioning Salt */
131
132 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
133 u32_t id; /* Link ID */
134 #endif
135
136 struct {
137 u8_t id; /* Transaction ID */
138 u8_t prev_id; /* Previous Transaction ID */
139 u8_t seg; /* Bit-field of unreceived segments */
140 u8_t last_seg; /* Last segment (to check length) */
141 u8_t fcs; /* Expected FCS value */
142 struct os_mbuf *buf;
143 } rx;
144
145 struct {
146 /* Start timestamp of the transaction */
147 s64_t start;
148
149 /* Transaction id*/
150 u8_t id;
151
152 /* Pending outgoing buffer(s) */
153 struct os_mbuf *buf[3];
154
155 /* Retransmit timer */
156 struct k_delayed_work retransmit;
157 } tx;
158 };
159
160 struct prov_rx {
161 u32_t link_id;
162 u8_t xact_id;
163 u8_t gpc;
164 };
165
166 #define RETRANSMIT_TIMEOUT K_MSEC(500)
167 #define BUF_TIMEOUT K_MSEC(400)
168 #define TRANSACTION_TIMEOUT K_SECONDS(30)
169
170 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
171 #define PROV_BUF_HEADROOM 5
172 #else
173 #define PROV_BUF_HEADROOM 0
174 static struct os_mbuf *rx_buf;
175 #endif
176
177 #define PROV_BUF(len) NET_BUF_SIMPLE(PROV_BUF_HEADROOM + len)
178
179 static struct prov_link link;
180
181 static const struct bt_mesh_prov *prov;
182
183 static void close_link(u8_t err, u8_t reason);
184
185 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
buf_sent(int err,void * user_data)186 static void buf_sent(int err, void *user_data)
187 {
188 BT_DBG("buf_sent");
189
190 if (!link.tx.buf[0]) {
191 return;
192 }
193
194 k_delayed_work_submit(&link.tx.retransmit, RETRANSMIT_TIMEOUT);
195 }
196
197 static struct bt_mesh_send_cb buf_sent_cb = {
198 .end = buf_sent,
199 };
200
free_segments(void)201 static void free_segments(void)
202 {
203 int i;
204
205 for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
206 struct os_mbuf *buf = link.tx.buf[i];
207
208 if (!buf) {
209 break;
210 }
211
212 link.tx.buf[i] = NULL;
213 /* Mark as canceled */
214 BT_MESH_ADV(buf)->busy = 0;
215 net_buf_unref(buf);
216 }
217 }
218
prov_clear_tx(void)219 static void prov_clear_tx(void)
220 {
221 BT_DBG("");
222
223 k_delayed_work_cancel(&link.tx.retransmit);
224
225 free_segments();
226 }
227
reset_link(void)228 static void reset_link(void)
229 {
230 atomic_clear_bit(link.flags, LINK_ACTIVE);
231
232 prov_clear_tx();
233
234 if (prov->link_close) {
235 prov->link_close(BT_MESH_PROV_ADV);
236 }
237
238 /* Clear everything except the retransmit delayed work config */
239 memset(&link, 0, offsetof(struct prov_link, tx.retransmit));
240
241 link.rx.prev_id = XACT_NVAL;
242
243 if (bt_pub_key_get()) {
244 atomic_set_bit(link.flags, LOCAL_PUB_KEY);
245 }
246
247 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
248 link.rx.buf = bt_mesh_proxy_get_buf();
249 #else
250 net_buf_simple_init(rx_buf, 0);
251 link.rx.buf = rx_buf;
252 #endif
253
254 /* Disable Attention Timer if it was set */
255 if (link.conf_inputs[0]) {
256 bt_mesh_attention(NULL, 0);
257 }
258 }
259
adv_buf_create(void)260 static struct os_mbuf *adv_buf_create(void)
261 {
262 struct os_mbuf *buf;
263
264 buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, PROV_XMIT, BUF_TIMEOUT);
265 if (!buf) {
266 BT_ERR("Out of provisioning buffers");
267 assert(0);
268 return NULL;
269 }
270
271 return buf;
272 }
273
274 static u8_t pending_ack = XACT_NVAL;
275
ack_complete(u16_t duration,int err,void * user_data)276 static void ack_complete(u16_t duration, int err, void *user_data)
277 {
278 BT_DBG("xact %u complete", (u8_t)pending_ack);
279 pending_ack = XACT_NVAL;
280 }
281
gen_prov_ack_send(u8_t xact_id)282 static void gen_prov_ack_send(u8_t xact_id)
283 {
284 static const struct bt_mesh_send_cb cb = {
285 .start = ack_complete,
286 };
287 const struct bt_mesh_send_cb *complete;
288 struct os_mbuf *buf;
289
290 BT_DBG("xact_id %u", xact_id);
291
292 if (pending_ack == xact_id) {
293 BT_DBG("Not sending duplicate ack");
294 return;
295 }
296
297 buf = adv_buf_create();
298 if (!buf) {
299 return;
300 }
301
302 if (pending_ack == XACT_NVAL) {
303 pending_ack = xact_id;
304 complete = &cb;
305 } else {
306 complete = NULL;
307 }
308
309 net_buf_add_be32(buf, link.id);
310 net_buf_add_u8(buf, xact_id);
311 net_buf_add_u8(buf, GPC_ACK);
312
313 bt_mesh_adv_send(buf, complete, NULL);
314 net_buf_unref(buf);
315 }
316
send_reliable(void)317 static void send_reliable(void)
318 {
319 int i;
320
321 link.tx.start = k_uptime_get();
322
323 for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
324 struct os_mbuf *buf = link.tx.buf[i];
325
326 if (!buf) {
327 break;
328 }
329
330 if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) {
331 bt_mesh_adv_send(buf, NULL, NULL);
332 } else {
333 bt_mesh_adv_send(buf, &buf_sent_cb, NULL);
334 }
335 }
336 }
337
bearer_ctl_send(u8_t op,void * data,u8_t data_len)338 static int bearer_ctl_send(u8_t op, void *data, u8_t data_len)
339 {
340 struct os_mbuf *buf;
341
342 BT_DBG("op 0x%02x data_len %u", op, data_len);
343
344 prov_clear_tx();
345
346 buf = adv_buf_create();
347 if (!buf) {
348 return -ENOBUFS;
349 }
350
351 net_buf_add_be32(buf, link.id);
352 /* Transaction ID, always 0 for Bearer messages */
353 net_buf_add_u8(buf, 0x00);
354 net_buf_add_u8(buf, GPC_CTL(op));
355 net_buf_add_mem(buf, data, data_len);
356
357 link.tx.buf[0] = buf;
358 send_reliable();
359
360 return 0;
361 }
362
last_seg(u8_t len)363 static u8_t last_seg(u8_t len)
364 {
365 if (len <= START_PAYLOAD_MAX) {
366 return 0;
367 }
368
369 len -= START_PAYLOAD_MAX;
370
371 return 1 + (len / CONT_PAYLOAD_MAX);
372 }
373
next_transaction_id(void)374 static inline u8_t next_transaction_id(void)
375 {
376 if (link.tx.id != 0 && link.tx.id != 0xFF) {
377 return ++link.tx.id;
378 }
379
380 link.tx.id = 0x80;
381 return link.tx.id;
382 }
383
prov_send_adv(struct os_mbuf * msg)384 static int prov_send_adv(struct os_mbuf *msg)
385 {
386 struct os_mbuf *start, *buf;
387 u8_t seg_len, seg_id;
388 u8_t xact_id;
389
390 BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len));
391
392 prov_clear_tx();
393
394 start = adv_buf_create();
395 if (!start) {
396 return -ENOBUFS;
397 }
398
399 xact_id = next_transaction_id();
400 net_buf_add_be32(start, link.id);
401 net_buf_add_u8(start, xact_id);
402
403 net_buf_add_u8(start, GPC_START(last_seg(msg->om_len)));
404 net_buf_add_be16(start, msg->om_len);
405 net_buf_add_u8(start, bt_mesh_fcs_calc(msg->om_data, msg->om_len));
406
407 link.tx.buf[0] = start;
408
409 seg_len = min(msg->om_len, START_PAYLOAD_MAX);
410 BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->om_data, seg_len));
411 net_buf_add_mem(start, msg->om_data, seg_len);
412 net_buf_simple_pull(msg, seg_len);
413
414 buf = start;
415 for (seg_id = 1; msg->om_len > 0; seg_id++) {
416 if (seg_id >= ARRAY_SIZE(link.tx.buf)) {
417 BT_ERR("Too big message");
418 free_segments();
419 return -E2BIG;
420 }
421
422 buf = adv_buf_create();
423 if (!buf) {
424 free_segments();
425 return -ENOBUFS;
426 }
427
428 link.tx.buf[seg_id] = buf;
429
430 seg_len = min(msg->om_len, CONT_PAYLOAD_MAX);
431
432 BT_DBG("seg_id %u len %u: %s", seg_id, seg_len,
433 bt_hex(msg->om_data, seg_len));
434
435 net_buf_add_be32(buf, link.id);
436 net_buf_add_u8(buf, xact_id);
437 net_buf_add_u8(buf, GPC_CONT(seg_id));
438 net_buf_add_mem(buf, msg->om_data, seg_len);
439 net_buf_simple_pull(msg, seg_len);
440 }
441
442 send_reliable();
443
444 return 0;
445 }
446
447 #endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */
448
449 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
prov_send_gatt(struct os_mbuf * msg)450 static int prov_send_gatt(struct os_mbuf *msg)
451 {
452 if (!link.conn_handle) {
453 BT_ERR("No connection handle!?");
454 return -ENOTCONN;
455 }
456
457 return bt_mesh_proxy_send(link.conn_handle, BT_MESH_PROXY_PROV, msg);
458 }
459 #endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */
460
prov_send(struct os_mbuf * buf)461 static inline int prov_send(struct os_mbuf *buf)
462 {
463 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
464 if (link.conn_handle) {
465 return prov_send_gatt(buf);
466 }
467 #endif
468 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
469 return prov_send_adv(buf);
470 #else
471 return 0;
472 #endif
473 }
474
prov_buf_init(struct os_mbuf * buf,u8_t type)475 static void prov_buf_init(struct os_mbuf *buf, u8_t type)
476 {
477 net_buf_simple_init(buf, PROV_BUF_HEADROOM);
478 net_buf_simple_add_u8(buf, type);
479 }
480
prov_send_fail_msg(u8_t err)481 static void prov_send_fail_msg(u8_t err)
482 {
483 struct os_mbuf *buf = PROV_BUF(2);
484
485 prov_buf_init(buf, PROV_FAILED);
486 net_buf_simple_add_u8(buf, err);
487 prov_send(buf);
488 os_mbuf_free_chain(buf);
489 }
490
prov_invite(const u8_t * data)491 static void prov_invite(const u8_t *data)
492 {
493 struct os_mbuf *buf = PROV_BUF(12);
494
495 BT_INFO("Attention Duration: %u seconds", data[0]);
496
497 if (data[0]) {
498 bt_mesh_attention(NULL, data[0]);
499 }
500
501 link.conf_inputs[0] = data[0];
502
503 prov_buf_init(buf, PROV_CAPABILITIES);
504
505 /* Number of Elements supported */
506 net_buf_simple_add_u8(buf, bt_mesh_elem_count());
507
508 /* Supported algorithms - FIPS P-256 Eliptic Curve */
509 net_buf_simple_add_be16(buf, BIT(PROV_ALG_P256));
510
511 /* Public Key Type */
512 /*PTS OOB*/
513 net_buf_simple_add_u8(buf, 0x00);
514
515 /* Static OOB Type */
516 net_buf_simple_add_u8(buf, prov->static_val ? BIT(0) : 0x00);
517
518 /* Output OOB Size */
519 net_buf_simple_add_u8(buf, prov->output_size);
520
521 /* Output OOB Action */
522 net_buf_simple_add_be16(buf, prov->output_actions);
523
524 /* Input OOB Size */
525 net_buf_simple_add_u8(buf, prov->input_size);
526
527 /* Input OOB Action */
528 net_buf_simple_add_be16(buf, prov->input_actions);
529
530 memcpy(&link.conf_inputs[1], &buf->om_data[1], 11);
531
532 if (prov_send(buf)) {
533 BT_ERR("Failed to send capabilities");
534 close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
535 goto done;
536 }
537
538 link.expect = PROV_START;
539
540 done:
541 os_mbuf_free_chain(buf);
542 }
543
prov_capabilities(const u8_t * data)544 static void prov_capabilities(const u8_t *data)
545 {
546 u16_t algorithms, output_action, input_action;
547
548 BT_INFO("Elements: %u", data[0]);
549
550 algorithms = sys_get_be16(&data[1]);
551 BT_INFO("Algorithms: %u", algorithms);
552
553 BT_INFO("Public Key Type: 0x%02x", data[3]);
554 BT_INFO("Static OOB Type: 0x%02x", data[4]);
555 BT_INFO("Output OOB Size: %u", data[5]);
556
557 output_action = sys_get_be16(&data[6]);
558 BT_INFO("Output OOB Action: 0x%04x", output_action);
559
560 BT_INFO("Input OOB Size: %u", data[8]);
561
562 input_action = sys_get_be16(&data[9]);
563 BT_INFO("Input OOB Action: 0x%04x", input_action);
564 }
565
output_action(u8_t action)566 static bt_mesh_output_action_t output_action(u8_t action)
567 {
568 switch (action) {
569 case OUTPUT_OOB_BLINK:
570 return BT_MESH_BLINK;
571 case OUTPUT_OOB_BEEP:
572 return BT_MESH_BEEP;
573 case OUTPUT_OOB_VIBRATE:
574 return BT_MESH_VIBRATE;
575 case OUTPUT_OOB_NUMBER:
576 return BT_MESH_DISPLAY_NUMBER;
577 case OUTPUT_OOB_STRING:
578 return BT_MESH_DISPLAY_STRING;
579 default:
580 return BT_MESH_NO_OUTPUT;
581 }
582 }
583
input_action(u8_t action)584 static bt_mesh_input_action_t input_action(u8_t action)
585 {
586 switch (action) {
587 case INPUT_OOB_PUSH:
588 return BT_MESH_PUSH;
589 case INPUT_OOB_TWIST:
590 return BT_MESH_TWIST;
591 case INPUT_OOB_NUMBER:
592 return BT_MESH_ENTER_NUMBER;
593 case INPUT_OOB_STRING:
594 return BT_MESH_ENTER_STRING;
595 default:
596 return BT_MESH_NO_INPUT;
597 }
598 }
599
prov_auth(u8_t method,u8_t action,u8_t size)600 static int prov_auth(u8_t method, u8_t action, u8_t size)
601 {
602 bt_mesh_output_action_t output;
603 bt_mesh_input_action_t input;
604
605 switch (method) {
606 case AUTH_METHOD_NO_OOB:
607 if (action || size) {
608 return -EINVAL;
609 }
610
611 memset(link.auth, 0, sizeof(link.auth));
612 return 0;
613 case AUTH_METHOD_STATIC:
614 if (action || size) {
615 return -EINVAL;
616 }
617
618 memcpy(link.auth + 16 - prov->static_val_len,
619 prov->static_val, prov->static_val_len);
620 memset(link.auth, 0, sizeof(link.auth) - prov->static_val_len);
621 return 0;
622
623 case AUTH_METHOD_OUTPUT:
624 output = output_action(action);
625 if (!output) {
626 return -EINVAL;
627 }
628
629 if (!(prov->output_actions & output)) {
630 return -EINVAL;
631 }
632
633 if (size > prov->output_size) {
634 return -EINVAL;
635 }
636
637 if (output == BT_MESH_DISPLAY_STRING) {
638 unsigned char str[9];
639 u8_t i;
640
641 bt_rand(str, size);
642
643 /* Normalize to '0' .. '9' & 'A' .. 'Z' */
644 for (i = 0; i < size; i++) {
645 str[i] %= 36;
646 if (str[i] < 10) {
647 str[i] += '0';
648 } else {
649 str[i] += 'A' - 10;
650 }
651 }
652 str[size] = '\0';
653
654 memcpy(link.auth, str, size);
655 memset(link.auth + size, 0, sizeof(link.auth) - size);
656
657 return prov->output_string((char *)str);
658 } else {
659 u32_t div[8] = { 10, 100, 1000, 10000, 100000,
660 1000000, 10000000, 100000000 };
661 u32_t num;
662
663 bt_rand(&num, sizeof(num));
664 num %= div[size - 1];
665
666 sys_put_be32(num, &link.auth[12]);
667 memset(link.auth, 0, 12);
668
669 return prov->output_number(output, num);
670 }
671
672 case AUTH_METHOD_INPUT:
673 input = input_action(action);
674 if (!input) {
675 return -EINVAL;
676 }
677
678 if (!(prov->input_actions & input)) {
679 return -EINVAL;
680 }
681
682 if (size > prov->input_size) {
683 return -EINVAL;
684 }
685
686 if (input == BT_MESH_ENTER_STRING) {
687 atomic_set_bit(link.flags, WAIT_STRING);
688 } else {
689 atomic_set_bit(link.flags, WAIT_NUMBER);
690 }
691
692 return prov->input(input, size);
693
694 default:
695 return -EINVAL;
696 }
697 }
698
prov_start(const u8_t * data)699 static void prov_start(const u8_t *data)
700 {
701 BT_INFO("Algorithm: 0x%02x", data[0]);
702 BT_INFO("Public Key: 0x%02x", data[1]);
703 BT_INFO("Auth Method: 0x%02x", data[2]);
704 BT_INFO("Auth Action: 0x%02x", data[3]);
705 BT_INFO("Auth Size: 0x%02x", data[4]);
706
707 if (data[0] != PROV_ALG_P256) {
708 BT_ERR("Unknown algorithm 0x%02x", data[0]);
709 prov_send_fail_msg(PROV_ERR_NVAL_FMT);
710 return;
711 }
712
713 if (data[1] > 0x01) {
714 BT_ERR("Invalid public key value: 0x%02x", data[1]);
715 prov_send_fail_msg(PROV_ERR_NVAL_FMT);
716 return;
717 }
718
719 memcpy(&link.conf_inputs[12], data, 5);
720
721 /* TODO: reset link when auth fails? */
722 link.expect = PROV_PUB_KEY;
723
724 if (prov_auth(data[2], data[3], data[4]) < 0) {
725 BT_ERR("Invalid authentication method: 0x%02x; "
726 "action: 0x%02x; size: 0x%02x", data[2], data[3],
727 data[4]);
728 prov_send_fail_msg(PROV_ERR_NVAL_FMT);
729 }
730 }
731
send_confirm(void)732 static void send_confirm(void)
733 {
734 struct os_mbuf *cfm = PROV_BUF(17);
735
736 BT_DBG("ConfInputs[0] %s", bt_hex(link.conf_inputs, 64));
737 BT_DBG("ConfInputs[64] %s", bt_hex(&link.conf_inputs[64], 64));
738 BT_DBG("ConfInputs[128] %s", bt_hex(&link.conf_inputs[128], 17));
739
740 if (bt_mesh_prov_conf_salt(link.conf_inputs, link.conf_salt)) {
741 BT_ERR("Unable to generate confirmation salt");
742 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
743 goto done;
744 }
745
746 BT_DBG("ConfirmationSalt: %s", bt_hex(link.conf_salt, 16));
747
748 if (bt_mesh_prov_conf_key(link.dhkey, link.conf_salt, link.conf_key)) {
749 BT_ERR("Unable to generate confirmation key");
750 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
751 goto done;
752 }
753
754 BT_DBG("ConfirmationKey: %s", bt_hex(link.conf_key, 16));
755
756 if (bt_rand(link.rand, 16)) {
757 BT_ERR("Unable to generate random number");
758 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
759 goto done;
760 }
761
762 BT_DBG("LocalRandom: %s", bt_hex(link.rand, 16));
763
764 prov_buf_init(cfm, PROV_CONFIRM);
765
766 if (bt_mesh_prov_conf(link.conf_key, link.rand, link.auth,
767 net_buf_simple_add(cfm, 16))) {
768 BT_ERR("Unable to generate confirmation value");
769 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
770 goto done;
771 }
772
773 if (prov_send(cfm)) {
774 BT_ERR("Failed to send Provisioning Confirm");
775 close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
776 goto done;
777 }
778
779 link.expect = PROV_RANDOM;
780
781 done:
782 os_mbuf_free_chain(cfm);
783 }
784
send_input_complete(void)785 static void send_input_complete(void)
786 {
787 struct os_mbuf *buf = PROV_BUF(1);
788
789 prov_buf_init(buf, PROV_INPUT_COMPLETE);
790 prov_send(buf);
791
792 os_mbuf_free_chain(buf);
793 }
794
bt_mesh_input_number(u32_t num)795 int bt_mesh_input_number(u32_t num)
796 {
797 BT_DBG("%u", num);
798
799 if (!atomic_test_and_clear_bit(link.flags, WAIT_NUMBER)) {
800 return -EINVAL;
801 }
802
803 sys_put_be32(num, &link.auth[12]);
804
805 send_input_complete();
806
807 if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
808 return 0;
809 }
810
811 if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
812 send_confirm();
813 }
814
815 return 0;
816 }
817
bt_mesh_input_string(const char * str)818 int bt_mesh_input_string(const char *str)
819 {
820 BT_DBG("%s", str);
821
822 if (!atomic_test_and_clear_bit(link.flags, WAIT_STRING)) {
823 return -EINVAL;
824 }
825
826 strncpy((char *)link.auth, str, prov->input_size);
827
828 send_input_complete();
829
830 if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
831 return 0;
832 }
833
834 if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
835 send_confirm();
836 }
837
838 return 0;
839 }
840
prov_dh_key_cb(const u8_t key[32])841 static void prov_dh_key_cb(const u8_t key[32])
842 {
843 BT_DBG("%p", key);
844
845 if (!key) {
846 BT_ERR("DHKey generation failed");
847 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
848 return;
849 }
850
851 sys_memcpy_swap(link.dhkey, key, 32);
852
853 BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32));
854
855 atomic_set_bit(link.flags, HAVE_DHKEY);
856
857 if (atomic_test_bit(link.flags, WAIT_NUMBER) ||
858 atomic_test_bit(link.flags, WAIT_STRING)) {
859 return;
860 }
861
862 if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
863 send_confirm();
864 }
865 }
866
send_pub_key(void)867 static void send_pub_key(void)
868 {
869 struct os_mbuf *buf = PROV_BUF(65);
870 const u8_t *key;
871
872 key = bt_pub_key_get();
873 if (!key) {
874 BT_ERR("No public key available");
875 close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
876 goto done;
877 }
878
879 prov_buf_init(buf, PROV_PUB_KEY);
880
881 /* Swap X and Y halves independently to big-endian */
882 sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32);
883 sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32);
884
885 memcpy(&link.conf_inputs[81], &buf->om_data[1], 64);
886
887 BT_DBG("Local Public Key: %s", bt_hex(&buf->om_data[1], 64));
888
889 prov_send(buf);
890
891 /* Copy remote key in little-endian for bt_dh_key_gen().
892 * X and Y halves are swapped independently.
893 */
894 net_buf_simple_init(buf, 0);
895 sys_memcpy_swap(buf->om_data, &link.conf_inputs[17], 32);
896 sys_memcpy_swap(&buf->om_data[32], &link.conf_inputs[49], 32);
897
898 if (bt_dh_key_gen(buf->om_data, prov_dh_key_cb)) {
899 BT_ERR("Failed to generate DHKey");
900 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
901 goto done;
902 }
903
904 link.expect = PROV_CONFIRM;
905
906 done:
907 os_mbuf_free_chain(buf);
908 }
909
prov_pub_key(const u8_t * data)910 static void prov_pub_key(const u8_t *data)
911 {
912 BT_INFO("Remote Public Key: %s", bt_hex(data, 64));
913
914 memcpy(&link.conf_inputs[17], data, 64);
915
916 if (!atomic_test_bit(link.flags, LOCAL_PUB_KEY)) {
917 /* Clear retransmit timer */
918 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
919 prov_clear_tx();
920 #endif
921 atomic_set_bit(link.flags, REMOTE_PUB_KEY);
922 BT_WARN("Waiting for local public key");
923 return;
924 }
925
926 send_pub_key();
927 }
928
pub_key_ready(const u8_t * pkey)929 static void pub_key_ready(const u8_t *pkey)
930 {
931 if (!pkey) {
932 BT_WARN("Public key not available");
933 return;
934 }
935
936 BT_DBG("Local public key ready");
937
938 atomic_set_bit(link.flags, LOCAL_PUB_KEY);
939
940 if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) {
941 send_pub_key();
942 }
943 }
944
prov_input_complete(const u8_t * data)945 static void prov_input_complete(const u8_t *data)
946 {
947 BT_DBG("");
948 }
949
prov_confirm(const u8_t * data)950 static void prov_confirm(const u8_t *data)
951 {
952 BT_INFO("Remote Confirm: %s", bt_hex(data, 16));
953
954 memcpy(link.conf, data, 16);
955
956 if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
957 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
958 prov_clear_tx();
959 #endif
960 atomic_set_bit(link.flags, SEND_CONFIRM);
961 } else {
962 send_confirm();
963 }
964 }
965
prov_random(const u8_t * data)966 static void prov_random(const u8_t *data)
967 {
968 struct os_mbuf *rnd = PROV_BUF(16);
969 u8_t conf_verify[16];
970
971 BT_INFO("Remote Random: %s", bt_hex(data, 16));
972
973 if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) {
974 BT_ERR("Unable to calculate confirmation verification");
975 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
976 goto done;
977 }
978
979 if (memcmp(conf_verify, link.conf, 16)) {
980 BT_ERR("Invalid confirmation value");
981 BT_DBG("Received: %s", bt_hex(link.conf, 16));
982 BT_DBG("Calculated: %s", bt_hex(conf_verify, 16));
983 close_link(PROV_ERR_CFM_FAILED, CLOSE_REASON_FAILED);
984 goto done;
985 }
986
987 prov_buf_init(rnd, PROV_RANDOM);
988 net_buf_simple_add_mem(rnd, link.rand, 16);
989
990 if (prov_send(rnd)) {
991 BT_ERR("Failed to send Provisioning Random");
992 close_link(PROV_ERR_RESOURCES, CLOSE_REASON_FAILED);
993 goto done;
994 }
995
996 if (bt_mesh_prov_salt(link.conf_salt, data, link.rand,
997 link.prov_salt)) {
998 BT_ERR("Failed to generate provisioning salt");
999 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1000 goto done;
1001 }
1002
1003 BT_DBG("ProvisioningSalt: %s", bt_hex(link.prov_salt, 16));
1004
1005 link.expect = PROV_DATA;
1006
1007 done:
1008 os_mbuf_free_chain(rnd);
1009 }
1010
is_pb_gatt(void)1011 static inline bool is_pb_gatt(void)
1012 {
1013 #if MYNEWT_VAL(BLE_MESH_PB_GATT)
1014 return !!link.conn_handle;
1015 #else
1016 return false;
1017 #endif
1018 }
1019
prov_data(const u8_t * data)1020 static void prov_data(const u8_t *data)
1021 {
1022 struct os_mbuf *msg = PROV_BUF(1);
1023 u8_t session_key[16];
1024 u8_t nonce[13];
1025 u8_t dev_key[16];
1026 u8_t pdu[25];
1027 u8_t flags;
1028 u32_t iv_index;
1029 u16_t addr;
1030 u16_t net_idx;
1031 int err;
1032 bool identity_enable;
1033
1034 BT_DBG("");
1035
1036 err = bt_mesh_session_key(link.dhkey, link.prov_salt, session_key);
1037 if (err) {
1038 BT_ERR("Unable to generate session key");
1039 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1040 goto done;
1041 }
1042
1043 BT_DBG("SessionKey: %s", bt_hex(session_key, 16));
1044
1045 err = bt_mesh_prov_nonce(link.dhkey, link.prov_salt, nonce);
1046 if (err) {
1047 BT_ERR("Unable to generate session nonce");
1048 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1049 goto done;
1050 }
1051
1052 BT_DBG("Nonce: %s", bt_hex(nonce, 13));
1053
1054 err = bt_mesh_prov_decrypt(session_key, nonce, data, pdu);
1055 if (err) {
1056 BT_ERR("Unable to decrypt provisioning data");
1057 close_link(PROV_ERR_DECRYPT, CLOSE_REASON_FAILED);
1058 goto done;
1059 }
1060
1061 err = bt_mesh_dev_key(link.dhkey, link.prov_salt, dev_key);
1062 if (err) {
1063 BT_ERR("Unable to generate device key");
1064 close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED);
1065 goto done;
1066 }
1067
1068 BT_DBG("DevKey: %s", bt_hex(dev_key, 16));
1069
1070 net_idx = sys_get_be16(&pdu[16]);
1071 flags = pdu[18];
1072 iv_index = sys_get_be32(&pdu[19]);
1073 addr = sys_get_be16(&pdu[23]);
1074
1075 BT_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x",
1076 net_idx, iv_index, addr);
1077
1078 prov_buf_init(msg, PROV_COMPLETE);
1079 prov_send(msg);
1080
1081 /* Ignore any further PDUs on this link */
1082 link.expect = 0;
1083
1084 /* Store info, since bt_mesh_provision() will end up clearing it */
1085 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
1086 identity_enable = is_pb_gatt();
1087 } else {
1088 identity_enable = false;
1089 }
1090
1091 bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key);
1092
1093 /* After PB-GATT provisioning we should start advertising
1094 * using Node Identity.
1095 */
1096 if (identity_enable) {
1097 bt_mesh_proxy_identity_enable();
1098 }
1099
1100 done:
1101 os_mbuf_free_chain(msg);
1102 }
1103
prov_complete(const u8_t * data)1104 static void prov_complete(const u8_t *data)
1105 {
1106 BT_INFO("");
1107 }
1108
prov_failed(const u8_t * data)1109 static void prov_failed(const u8_t *data)
1110 {
1111 BT_WARN("Error: 0x%02x", data[0]);
1112 }
1113
1114 static const struct {
1115 void (*func)(const u8_t *data);
1116 u16_t len;
1117 } prov_handlers[] = {
1118 { prov_invite, 1 },
1119 { prov_capabilities, 11 },
1120 { prov_start, 5, },
1121 { prov_pub_key, 64 },
1122 { prov_input_complete, 0 },
1123 { prov_confirm, 16 },
1124 { prov_random, 16 },
1125 { prov_data, 33 },
1126 { prov_complete, 0 },
1127 { prov_failed, 1 },
1128 };
1129
close_link(u8_t err,u8_t reason)1130 static void close_link(u8_t err, u8_t reason)
1131 {
1132 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
1133 if (link.conn_handle) {
1134 bt_mesh_pb_gatt_close(link.conn_handle);
1135 return;
1136 }
1137 #endif
1138
1139 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
1140 if (err) {
1141 prov_send_fail_msg(err);
1142 }
1143
1144 link.rx.seg = 0;
1145 bearer_ctl_send(LINK_CLOSE, &reason, sizeof(reason));
1146 #endif
1147
1148 atomic_clear_bit(link.flags, LINK_ACTIVE);
1149
1150 /* Disable Attention Timer if it was set */
1151 if (link.conf_inputs[0]) {
1152 bt_mesh_attention(NULL, 0);
1153 }
1154 }
1155
1156 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
prov_retransmit(struct ble_npl_event * work)1157 static void prov_retransmit(struct ble_npl_event *work)
1158 {
1159 int i;
1160
1161 BT_DBG("");
1162
1163 if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
1164 BT_WARN("Link not active");
1165 return;
1166 }
1167
1168 if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) {
1169 BT_WARN("Giving up transaction");
1170 reset_link();
1171 return;
1172 }
1173
1174 for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) {
1175 struct os_mbuf *buf = link.tx.buf[i];
1176
1177 if (!buf) {
1178 break;
1179 }
1180
1181 if (BT_MESH_ADV(buf)->busy) {
1182 continue;
1183 }
1184
1185 BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
1186
1187 if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) {
1188 bt_mesh_adv_send(buf, NULL, NULL);
1189 } else {
1190 bt_mesh_adv_send(buf, &buf_sent_cb, NULL);
1191 }
1192
1193 }
1194 }
1195
link_open(struct prov_rx * rx,struct os_mbuf * buf)1196 static void link_open(struct prov_rx *rx, struct os_mbuf *buf)
1197 {
1198 BT_INFO("link open: len %u", buf->om_len);
1199
1200 if (buf->om_len < 16) {
1201 BT_ERR("Too short bearer open message (len %u)", buf->om_len);
1202 return;
1203 }
1204
1205 if (atomic_test_bit(link.flags, LINK_ACTIVE)) {
1206 /* Send another link ack if the provisioner missed the last */
1207 if (link.id == rx->link_id && link.expect == PROV_INVITE) {
1208 BT_DBG("Resending link ack");
1209 bearer_ctl_send(LINK_ACK, NULL, 0);
1210 } else {
1211 BT_WARN("Ignoring bearer open: link already active");
1212 }
1213
1214 return;
1215 }
1216
1217 if (memcmp(buf->om_data, prov->uuid, 16)) {
1218 BT_DBG("Bearer open message not for us");
1219 return;
1220 }
1221
1222 if (prov->link_open) {
1223 prov->link_open(BT_MESH_PROV_ADV);
1224 }
1225
1226 link.id = rx->link_id;
1227 atomic_set_bit(link.flags, LINK_ACTIVE);
1228 net_buf_simple_init(link.rx.buf, 0);
1229
1230 bearer_ctl_send(LINK_ACK, NULL, 0);
1231
1232 link.expect = PROV_INVITE;
1233 }
1234
link_ack(struct prov_rx * rx,struct os_mbuf * buf)1235 static void link_ack(struct prov_rx *rx, struct os_mbuf *buf)
1236 {
1237 BT_INFO("Link ack: len %u", buf->om_len);
1238 }
1239
link_close(struct prov_rx * rx,struct os_mbuf * buf)1240 static void link_close(struct prov_rx *rx, struct os_mbuf *buf)
1241 {
1242 BT_INFO("Link close: len %u", buf->om_len);
1243
1244 reset_link();
1245 }
1246
gen_prov_ctl(struct prov_rx * rx,struct os_mbuf * buf)1247 static void gen_prov_ctl(struct prov_rx *rx, struct os_mbuf *buf)
1248 {
1249 BT_DBG("op 0x%02x len %u", BEARER_CTL(rx->gpc), buf->om_len);
1250
1251 switch (BEARER_CTL(rx->gpc)) {
1252 case LINK_OPEN:
1253 link_open(rx, buf);
1254 break;
1255 case LINK_ACK:
1256 if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
1257 return;
1258 }
1259
1260 link_ack(rx, buf);
1261 break;
1262 case LINK_CLOSE:
1263 if (!atomic_test_bit(link.flags, LINK_ACTIVE)) {
1264 return;
1265 }
1266
1267 link_close(rx, buf);
1268 break;
1269 default:
1270 BT_ERR("Unknown bearer opcode: 0x%02x", BEARER_CTL(rx->gpc));
1271
1272 if (IS_ENABLED(CONFIG_BT_TESTING)) {
1273 bt_test_mesh_prov_invalid_bearer(BEARER_CTL(rx->gpc));
1274 }
1275
1276 return;
1277 }
1278 }
1279
prov_msg_recv(void)1280 static void prov_msg_recv(void)
1281 {
1282 u8_t type = link.rx.buf->om_data[0];
1283
1284 BT_DBG("type 0x%02x len %u", type, link.rx.buf->om_len);
1285
1286 if (!bt_mesh_fcs_check(link.rx.buf, link.rx.fcs)) {
1287 BT_ERR("Incorrect FCS");
1288 return;
1289 }
1290
1291 gen_prov_ack_send(link.rx.id);
1292 link.rx.prev_id = link.rx.id;
1293 link.rx.id = 0;
1294
1295 if (type != PROV_FAILED && type != link.expect) {
1296 BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
1297 prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
1298 return;
1299 }
1300
1301 if (type >= ARRAY_SIZE(prov_handlers)) {
1302 BT_ERR("Unknown provisioning PDU type 0x%02x", type);
1303 close_link(PROV_ERR_NVAL_PDU, CLOSE_REASON_FAILED);
1304 return;
1305 }
1306
1307 if (1 + prov_handlers[type].len != link.rx.buf->om_len) {
1308 BT_ERR("Invalid length %u for type 0x%02x",
1309 link.rx.buf->om_len, type);
1310 close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1311 return;
1312 }
1313
1314 prov_handlers[type].func(&link.rx.buf->om_data[1]);
1315 }
1316
gen_prov_cont(struct prov_rx * rx,struct os_mbuf * buf)1317 static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf)
1318 {
1319 u8_t seg = CONT_SEG_INDEX(rx->gpc);
1320
1321 BT_DBG("len %u, seg_index %u", buf->om_len, seg);
1322
1323 if (!link.rx.seg && link.rx.prev_id == rx->xact_id) {
1324 BT_WARN("Resending ack");
1325 gen_prov_ack_send(rx->xact_id);
1326 return;
1327 }
1328
1329 if (rx->xact_id != link.rx.id) {
1330 BT_WARN("Data for unknown transaction (%u != %u)",
1331 rx->xact_id, link.rx.id);
1332 return;
1333 }
1334
1335 if (seg > link.rx.last_seg) {
1336 BT_ERR("Invalid segment index %u", seg);
1337 close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1338 return;
1339 } else if (seg == link.rx.last_seg) {
1340 u8_t expect_len;
1341
1342 expect_len = (link.rx.buf->om_len - 20 -
1343 (23 * (link.rx.last_seg - 1)));
1344 if (expect_len != buf->om_len) {
1345 BT_ERR("Incorrect last seg len: %u != %u",
1346 expect_len, buf->om_len);
1347 close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1348 return;
1349 }
1350 }
1351
1352 if (!(link.rx.seg & BIT(seg))) {
1353 BT_WARN("Ignoring already received segment");
1354 return;
1355 }
1356
1357 memcpy(XACT_SEG_DATA(seg), buf->om_data, buf->om_len);
1358 XACT_SEG_RECV(seg);
1359
1360 if (!link.rx.seg) {
1361 prov_msg_recv();
1362 }
1363 }
1364
gen_prov_ack(struct prov_rx * rx,struct os_mbuf * buf)1365 static void gen_prov_ack(struct prov_rx *rx, struct os_mbuf *buf)
1366 {
1367 BT_DBG("len %u", buf->om_len);
1368
1369 if (!link.tx.buf[0]) {
1370 return;
1371 }
1372
1373 if (rx->xact_id == link.tx.id) {
1374 prov_clear_tx();
1375 }
1376 }
1377
gen_prov_start(struct prov_rx * rx,struct os_mbuf * buf)1378 static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf)
1379 {
1380 u16_t trailing_space = 0;
1381
1382 if (link.rx.seg) {
1383 BT_WARN("Got Start while there are unreceived segments");
1384 return;
1385 }
1386
1387 if (link.rx.prev_id == rx->xact_id) {
1388 BT_WARN("Resending ack");
1389 gen_prov_ack_send(rx->xact_id);
1390 return;
1391 }
1392
1393 trailing_space = OS_MBUF_TRAILINGSPACE(link.rx.buf);
1394
1395 link.rx.buf->om_len = net_buf_simple_pull_be16(buf);
1396 link.rx.id = rx->xact_id;
1397 link.rx.fcs = net_buf_simple_pull_u8(buf);
1398
1399 BT_DBG("len %u last_seg %u total_len %u fcs 0x%02x", buf->om_len,
1400 START_LAST_SEG(rx->gpc), link.rx.buf->om_len, link.rx.fcs);
1401
1402 if (link.rx.buf->om_len < 1) {
1403 BT_ERR("Ignoring zero-length provisioning PDU");
1404 close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1405 return;
1406 }
1407
1408 if (link.rx.buf->om_len > trailing_space) {
1409 BT_ERR("Too large provisioning PDU (%u bytes)",
1410 link.rx.buf->om_len);
1411 close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1412 return;
1413 }
1414
1415 if (START_LAST_SEG(rx->gpc) > 0 && link.rx.buf->om_len <= 20) {
1416 BT_ERR("Too small total length for multi-segment PDU");
1417 close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED);
1418 return;
1419 }
1420
1421 link.rx.seg = (1 << (START_LAST_SEG(rx->gpc) + 1)) - 1;
1422 link.rx.last_seg = START_LAST_SEG(rx->gpc);
1423 memcpy(link.rx.buf->om_data, buf->om_data, buf->om_len);
1424 XACT_SEG_RECV(0);
1425
1426 if (!link.rx.seg) {
1427 prov_msg_recv();
1428 }
1429 }
1430
1431 static const struct {
1432 void (*const func)(struct prov_rx *rx, struct os_mbuf *buf);
1433 const u8_t require_link;
1434 const u8_t min_len;
1435 } gen_prov[] = {
1436 { gen_prov_start, true, 3 },
1437 { gen_prov_ack, true, 0 },
1438 { gen_prov_cont, true, 0 },
1439 { gen_prov_ctl, false, 0 },
1440 };
1441
gen_prov_recv(struct prov_rx * rx,struct os_mbuf * buf)1442 static void gen_prov_recv(struct prov_rx *rx, struct os_mbuf *buf)
1443 {
1444 if (buf->om_len < gen_prov[GPCF(rx->gpc)].min_len) {
1445 BT_ERR("Too short GPC message type %u", GPCF(rx->gpc));
1446 return;
1447 }
1448
1449 if (!atomic_test_bit(link.flags, LINK_ACTIVE) &&
1450 gen_prov[GPCF(rx->gpc)].require_link) {
1451 BT_DBG("Ignoring message that requires active link");
1452 return;
1453 }
1454
1455 BT_INFO("prov_action: %d", GPCF(rx->gpc));
1456 gen_prov[GPCF(rx->gpc)].func(rx, buf);
1457 }
1458
bt_mesh_pb_adv_recv(struct os_mbuf * buf)1459 void bt_mesh_pb_adv_recv(struct os_mbuf *buf)
1460 {
1461 struct prov_rx rx;
1462
1463 if (!bt_prov_active() && bt_mesh_is_provisioned()) {
1464 BT_DBG("Ignoring provisioning PDU - already provisioned");
1465 return;
1466 }
1467
1468 if (buf->om_len < 6) {
1469 BT_WARN("Too short provisioning packet (len %u)", buf->om_len);
1470 return;
1471 }
1472
1473 rx.link_id = net_buf_simple_pull_be32(buf);
1474 rx.xact_id = net_buf_simple_pull_u8(buf);
1475 rx.gpc = net_buf_simple_pull_u8(buf);
1476
1477 BT_DBG("link_id 0x%08x xact_id %u", rx.link_id, rx.xact_id);
1478
1479 if (atomic_test_bit(link.flags, LINK_ACTIVE) && link.id != rx.link_id) {
1480 BT_DBG("Ignoring mesh beacon for unknown link");
1481 return;
1482 }
1483
1484 gen_prov_recv(&rx, buf);
1485 }
1486 #endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */
1487
1488 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
bt_mesh_pb_gatt_recv(uint16_t conn_handle,struct os_mbuf * buf)1489 int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf)
1490 {
1491 u8_t type;
1492
1493 BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
1494
1495 if (link.conn_handle != conn_handle) {
1496 BT_WARN("Data for unexpected connection");
1497 return -ENOTCONN;
1498 }
1499
1500 if (buf->om_len < 1) {
1501 BT_WARN("Too short provisioning packet (len %u)", buf->om_len);
1502 return -EINVAL;
1503 }
1504
1505 type = net_buf_simple_pull_u8(buf);
1506 if (type != PROV_FAILED && type != link.expect) {
1507 BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
1508 prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
1509 return -EINVAL;
1510 }
1511
1512 if (type >= ARRAY_SIZE(prov_handlers)) {
1513 BT_ERR("Unknown provisioning PDU type 0x%02x", type);
1514 return -EINVAL;
1515 }
1516
1517 if (prov_handlers[type].len != buf->om_len) {
1518 BT_ERR("Invalid length %u for type 0x%02x", buf->om_len, type);
1519 return -EINVAL;
1520 }
1521
1522 prov_handlers[type].func(buf->om_data);
1523
1524 return 0;
1525 }
1526
bt_mesh_pb_gatt_open(uint16_t conn_handle)1527 int bt_mesh_pb_gatt_open(uint16_t conn_handle)
1528 {
1529 BT_DBG("conn_handle %d", conn_handle);
1530
1531 if (atomic_test_and_set_bit(link.flags, LINK_ACTIVE)) {
1532 BT_ERR("Link already opened?");
1533 return -EBUSY;
1534 }
1535
1536 link.conn_handle = conn_handle;
1537 link.expect = PROV_INVITE;
1538
1539 if (prov->link_open) {
1540 prov->link_open(BT_MESH_PROV_GATT);
1541 }
1542
1543 return 0;
1544 }
1545
bt_mesh_pb_gatt_close(uint16_t conn_handle)1546 int bt_mesh_pb_gatt_close(uint16_t conn_handle)
1547 {
1548 bool pub_key;
1549
1550 BT_DBG("conn_handle %d", conn_handle);
1551
1552 if (link.conn_handle != conn_handle) {
1553 BT_ERR("Not connected");
1554 return -ENOTCONN;
1555 }
1556
1557 /* Disable Attention Timer if it was set */
1558 if (link.conf_inputs[0]) {
1559 bt_mesh_attention(NULL, 0);
1560 }
1561
1562 if (prov->link_close) {
1563 prov->link_close(BT_MESH_PROV_GATT);
1564 }
1565
1566 // bt_conn_unref(conn_handle);
1567
1568 pub_key = atomic_test_bit(link.flags, LOCAL_PUB_KEY);
1569 memset(&link, 0, sizeof(link));
1570
1571 if (pub_key) {
1572 atomic_set_bit(link.flags, LOCAL_PUB_KEY);
1573 }
1574
1575 return 0;
1576 }
1577 #endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */
1578
bt_mesh_prov_get(void)1579 const struct bt_mesh_prov *bt_mesh_prov_get(void)
1580 {
1581 return prov;
1582 }
1583
bt_prov_active(void)1584 bool bt_prov_active(void)
1585 {
1586 return atomic_test_bit(link.flags, LINK_ACTIVE);
1587 }
1588
bt_mesh_prov_init(const struct bt_mesh_prov * prov_info)1589 int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info)
1590 {
1591 static struct bt_pub_key_cb pub_key_cb = {
1592 .func = pub_key_ready,
1593 };
1594 int err;
1595
1596 #if !(MYNEWT_VAL(BLE_MESH_PB_GATT))
1597 rx_buf = NET_BUF_SIMPLE(65);
1598 #endif
1599
1600 if (!prov_info) {
1601 BT_ERR("No provisioning context provided");
1602 return -EINVAL;
1603 }
1604
1605 err = bt_pub_key_gen(&pub_key_cb);
1606 if (err) {
1607 BT_ERR("Failed to generate public key (%d)", err);
1608 return err;
1609 }
1610
1611 prov = prov_info;
1612
1613 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
1614 k_delayed_work_init(&link.tx.retransmit, prov_retransmit);
1615 link.rx.prev_id = XACT_NVAL;
1616
1617 #if !(MYNEWT_VAL(BLE_MESH_PB_GATT))
1618 net_buf_simple_init(rx_buf, 0);
1619 link.rx.buf = rx_buf;
1620 #endif
1621
1622 #endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */
1623
1624 return 0;
1625 }
1626
bt_mesh_prov_reset_link(void)1627 void bt_mesh_prov_reset_link(void) {
1628 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
1629 link.rx.buf = bt_mesh_proxy_get_buf();
1630 #else
1631 net_buf_simple_init(rx_buf, 0);
1632 link.rx.buf = rx_buf;
1633 #endif
1634 }
1635
bt_mesh_prov_complete(u16_t net_idx,u16_t addr)1636 void bt_mesh_prov_complete(u16_t net_idx, u16_t addr)
1637 {
1638 if (prov->complete) {
1639 prov->complete(net_idx, addr);
1640 }
1641 }
1642
bt_mesh_prov_reset(void)1643 void bt_mesh_prov_reset(void)
1644 {
1645 if (prov->reset) {
1646 prov->reset();
1647 }
1648 }
1649
1650 #endif //MYNEWT_VAL(BLE_MESH_PROV) == 1
1651