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