From 5f56107d61e7b8154342531b950f038bced9d486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Mon, 1 Jul 2019 12:56:37 +0200 Subject: [PATCH] nimble/mesh: Sync provisioning code with Zephyr This patch contains a few proposed patches from Mynewt that were backported to Zephyr and since there were other differences in this file I decided to sync it in one commit. In sync with this PR: https://github.com/zephyrproject-rtos/zephyr/pull/17117 --- nimble/host/mesh/src/prov.c | 362 ++++++++++++++++-------------------- 1 file changed, 160 insertions(+), 202 deletions(-) diff --git a/nimble/host/mesh/src/prov.c b/nimble/host/mesh/src/prov.c index 88475c108..791938c54 100644 --- a/nimble/host/mesh/src/prov.c +++ b/nimble/host/mesh/src/prov.c @@ -101,13 +101,12 @@ enum { REMOTE_PUB_KEY, /* Remote key has been received */ - LOCAL_PUB_KEY, /* Local public key is available */ LINK_ACTIVE, /* Link has been opened */ - HAVE_DHKEY, /* DHKey has been calcualted */ + HAVE_DHKEY, /* DHKey has been calculated */ SEND_CONFIRM, /* Waiting to send Confirm value */ WAIT_NUMBER, /* Waiting for number input from user */ WAIT_STRING, /* Waiting for string input from user */ - LINK_INVALID, /* Error occured during provisioning */ + LINK_INVALID, /* Error occurred during provisioning */ NUM_FLAGS, }; @@ -135,7 +134,6 @@ struct prov_link { #if (MYNEWT_VAL(BLE_MESH_PB_ADV)) u32_t id; /* Link ID */ -#endif struct { u8_t id; /* Transaction ID */ @@ -159,6 +157,9 @@ struct prov_link { /* Retransmit timer */ struct k_delayed_work retransmit; } tx; +#endif + + struct k_delayed_work prot_timer; }; struct prov_rx { @@ -182,10 +183,56 @@ static struct os_mbuf *rx_buf; #define PROV_BUF(len) NET_BUF_SIMPLE(PROV_BUF_HEADROOM + len) static struct prov_link link; -static struct k_delayed_work prot_timer; + static const struct bt_mesh_prov *prov; -static void close_link(u8_t err, u8_t reason); +static void pub_key_ready(const u8_t *pkey); + +static int reset_state(void) +{ + static struct bt_pub_key_cb pub_key_cb = { + .func = pub_key_ready, + }; + int err; + + k_delayed_work_cancel(&link.prot_timer); + + /* Disable Attention Timer if it was set */ + if (link.conf_inputs[0]) { + bt_mesh_attention(NULL, 0); + } + +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + /* Clear everything except the retransmit and protocol timer + * delayed work objects. + */ + (void)memset(&link, 0, offsetof(struct prov_link, tx.retransmit)); + link.rx.prev_id = XACT_NVAL; + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + link.rx.buf = bt_mesh_proxy_get_buf(); +#else + net_buf_simple_init(rx_buf, 0); + link.rx.buf = rx_buf; +#endif /* PB_GATT */ + +#else /* !PB_ADV */ + /* Clear everything except the protocol timer (k_delayed_work) */ + (void)memset(&link, 0, offsetof(struct prov_link, prot_timer)); +#endif /* PB_ADV */ + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + link.conn_handle = BLE_HS_CONN_HANDLE_NONE; +#endif + + err = bt_pub_key_gen(&pub_key_cb); + if (err) { + BT_ERR("Failed to generate public key (%d)", err); + return err; + } + + return 0; +} #if (MYNEWT_VAL(BLE_MESH_PB_ADV)) static void buf_sent(int err, void *user_data) @@ -230,40 +277,15 @@ static void prov_clear_tx(void) free_segments(); } -static void reset_link(void) +static void reset_adv_link(void) { - atomic_clear_bit(link.flags, LINK_ACTIVE); - atomic_clear_bit(link.flags, LINK_INVALID); - k_delayed_work_cancel(&prot_timer); - prov_clear_tx(); if (prov->link_close) { prov->link_close(BT_MESH_PROV_ADV); } - /* Clear everything except the retransmit delayed work config */ - memset(&link, 0, offsetof(struct prov_link, tx.retransmit)); -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - link.conn_handle = BLE_HS_CONN_HANDLE_NONE; -#endif - link.rx.prev_id = XACT_NVAL; - - if (bt_pub_key_get()) { - atomic_set_bit(link.flags, LOCAL_PUB_KEY); - } - -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - link.rx.buf = bt_mesh_proxy_get_buf(); -#else - net_buf_simple_init(rx_buf, 0); - link.rx.buf = rx_buf; -#endif - - /* Disable Attention Timer if it was set */ - if (link.conf_inputs[0]) { - bt_mesh_attention(NULL, 0); - } + reset_state(); } static struct os_mbuf *adv_buf_create(void) @@ -469,7 +491,7 @@ static int prov_send_gatt(struct os_mbuf *msg) static inline int prov_send(struct os_mbuf *buf) { - k_delayed_work_submit(&prot_timer, PROTOCOL_TIMEOUT); + k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) if (link.conn_handle != BLE_HS_CONN_HANDLE_NONE) { @@ -495,7 +517,13 @@ static void prov_send_fail_msg(u8_t err) prov_buf_init(buf, PROV_FAILED); net_buf_simple_add_u8(buf, err); - prov_send(buf); + + if (prov_send(buf)) { + BT_ERR("Failed to send Provisioning Failed message"); + } + + atomic_set_bit(link.flags, LINK_INVALID); + os_mbuf_free_chain(buf); } @@ -503,7 +531,7 @@ static void prov_invite(const u8_t *data) { struct os_mbuf *buf = PROV_BUF(12); - BT_INFO("Attention Duration: %u seconds", data[0]); + BT_DBG("Attention Duration: %u seconds", data[0]); if (data[0]) { bt_mesh_attention(NULL, data[0]); @@ -519,8 +547,7 @@ static void prov_invite(const u8_t *data) /* Supported algorithms - FIPS P-256 Eliptic Curve */ net_buf_simple_add_be16(buf, BIT(PROV_ALG_P256)); - /* Public Key Type */ - /* Only No OOB Public Key is supported*/ + /* Public Key Type, Only "No OOB" Public Key is supported*/ net_buf_simple_add_u8(buf, PUB_KEY_NO_OOB); /* Static OOB Type */ @@ -542,8 +569,6 @@ static void prov_invite(const u8_t *data) if (prov_send(buf)) { BT_ERR("Failed to send capabilities"); - prov_send_fail_msg(PROV_ERR_RESOURCES); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -557,22 +582,22 @@ static void prov_capabilities(const u8_t *data) { u16_t algorithms, output_action, input_action; - BT_INFO("Elements: %u", data[0]); + BT_DBG("Elements: %u", data[0]); algorithms = sys_get_be16(&data[1]); - BT_INFO("Algorithms: %u", algorithms); + BT_DBG("Algorithms: %u", algorithms); - BT_INFO("Public Key Type: 0x%02x", data[3]); - BT_INFO("Static OOB Type: 0x%02x", data[4]); - BT_INFO("Output OOB Size: %u", data[5]); + BT_DBG("Public Key Type: 0x%02x", data[3]); + BT_DBG("Static OOB Type: 0x%02x", data[4]); + BT_DBG("Output OOB Size: %u", data[5]); output_action = sys_get_be16(&data[6]); - BT_INFO("Output OOB Action: 0x%04x", output_action); + BT_DBG("Output OOB Action: 0x%04x", output_action); - BT_INFO("Input OOB Size: %u", data[8]); + BT_DBG("Input OOB Size: %u", data[8]); input_action = sys_get_be16(&data[9]); - BT_INFO("Input OOB Action: 0x%04x", input_action); + BT_DBG("Input OOB Action: 0x%04x", input_action); } static bt_mesh_output_action_t output_action(u8_t action) @@ -710,23 +735,21 @@ static int prov_auth(u8_t method, u8_t action, u8_t size) static void prov_start(const u8_t *data) { - BT_INFO("Algorithm: 0x%02x", data[0]); - BT_INFO("Public Key: 0x%02x", data[1]); - BT_INFO("Auth Method: 0x%02x", data[2]); - BT_INFO("Auth Action: 0x%02x", data[3]); - BT_INFO("Auth Size: 0x%02x", data[4]); + BT_DBG("Algorithm: 0x%02x", data[0]); + BT_DBG("Public Key: 0x%02x", data[1]); + BT_DBG("Auth Method: 0x%02x", data[2]); + BT_DBG("Auth Action: 0x%02x", data[3]); + BT_DBG("Auth Size: 0x%02x", data[4]); if (data[0] != PROV_ALG_P256) { BT_ERR("Unknown algorithm 0x%02x", data[0]); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } if (data[1] != PUB_KEY_NO_OOB) { - BT_ERR("Invalid public key value: 0x%02x", data[1]); + BT_ERR("Invalid public key type: 0x%02x", data[1]); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } @@ -740,7 +763,6 @@ static void prov_start(const u8_t *data) "action: 0x%02x; size: 0x%02x", data[2], data[3], data[4]); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); } } @@ -755,7 +777,6 @@ static void send_confirm(void) if (bt_mesh_prov_conf_salt(link.conf_inputs, link.conf_salt)) { BT_ERR("Unable to generate confirmation salt"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -764,7 +785,6 @@ static void send_confirm(void) if (bt_mesh_prov_conf_key(link.dhkey, link.conf_salt, link.conf_key)) { BT_ERR("Unable to generate confirmation key"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -773,7 +793,6 @@ static void send_confirm(void) if (bt_rand(link.rand, 16)) { BT_ERR("Unable to generate random number"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -785,14 +804,11 @@ static void send_confirm(void) net_buf_simple_add(cfm, 16))) { BT_ERR("Unable to generate confirmation value"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } if (prov_send(cfm)) { BT_ERR("Failed to send Provisioning Confirm"); - prov_send_fail_msg(PROV_ERR_RESOURCES); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -807,7 +823,9 @@ static void send_input_complete(void) struct os_mbuf *buf = PROV_BUF(1); prov_buf_init(buf, PROV_INPUT_COMPLETE); - prov_send(buf); + if (prov_send(buf)) { + BT_ERR("Failed to send Provisioning Input Complete"); + } os_mbuf_free_chain(buf); } @@ -865,7 +883,6 @@ static void prov_dh_key_cb(const u8_t key[32]) if (!key) { BT_ERR("DHKey generation failed"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); return; } @@ -893,11 +910,26 @@ static void send_pub_key(void) key = bt_pub_key_get(); if (!key) { BT_ERR("No public key available"); - prov_send_fail_msg(PROV_ERR_RESOURCES); - atomic_set_bit(link.flags, LINK_INVALID); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); goto done; } + BT_DBG("Local Public Key: %s", bt_hex(key, 64)); + + /* Copy remote key in little-endian for bt_dh_key_gen(). + * X and Y halves are swapped independently. Use response + * buffer as a temporary storage location. The bt_dh_key_gen() + * will also take care of validating the remote public key. + */ + sys_memcpy_swap(buf->om_data, &link.conf_inputs[17], 32); + sys_memcpy_swap(&buf->om_data[32], &link.conf_inputs[49], 32); + + if (bt_dh_key_gen(buf->om_data, prov_dh_key_cb)) { + BT_ERR("Failed to generate DHKey"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + return; + } + prov_buf_init(buf, PROV_PUB_KEY); /* Swap X and Y halves independently to big-endian */ @@ -906,22 +938,9 @@ static void send_pub_key(void) memcpy(&link.conf_inputs[81], &buf->om_data[1], 64); - BT_DBG("Local Public Key: %s", bt_hex(&buf->om_data[1], 64)); - - prov_send(buf); - - /* Copy remote key in little-endian for bt_dh_key_gen(). - * X and Y halves are swapped independently. - */ - net_buf_simple_init(buf, 0); - sys_memcpy_swap(buf->om_data, &link.conf_inputs[17], 32); - sys_memcpy_swap(&buf->om_data[32], &link.conf_inputs[49], 32); - - if (bt_dh_key_gen(buf->om_data, prov_dh_key_cb)) { - BT_ERR("Failed to generate DHKey"); - prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); - goto done; + if (prov_send(buf)) { + BT_ERR("Failed to send Public Key"); + return; } link.expect = PROV_CONFIRM; @@ -932,11 +951,11 @@ done: static void prov_pub_key(const u8_t *data) { - BT_INFO("Remote Public Key: %s", bt_hex(data, 64)); + BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); memcpy(&link.conf_inputs[17], data, 64); - if (!atomic_test_bit(link.flags, LOCAL_PUB_KEY)) { + if (!bt_pub_key_get()) { /* Clear retransmit timer */ #if (MYNEWT_VAL(BLE_MESH_PB_ADV)) prov_clear_tx(); @@ -958,8 +977,6 @@ static void pub_key_ready(const u8_t *pkey) BT_DBG("Local public key ready"); - atomic_set_bit(link.flags, LOCAL_PUB_KEY); - if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) { send_pub_key(); } @@ -972,7 +989,7 @@ static void prov_input_complete(const u8_t *data) static void prov_confirm(const u8_t *data) { - BT_INFO("Remote Confirm: %s", bt_hex(data, 16)); + BT_DBG("Remote Confirm: %s", bt_hex(data, 16)); memcpy(link.conf, data, 16); @@ -991,12 +1008,11 @@ static void prov_random(const u8_t *data) struct os_mbuf *rnd = PROV_BUF(16); u8_t conf_verify[16]; - BT_INFO("Remote Random: %s", bt_hex(data, 16)); + BT_DBG("Remote Random: %s", bt_hex(data, 16)); if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) { BT_ERR("Unable to calculate confirmation verification"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -1005,7 +1021,6 @@ static void prov_random(const u8_t *data) BT_DBG("Received: %s", bt_hex(link.conf, 16)); BT_DBG("Calculated: %s", bt_hex(conf_verify, 16)); prov_send_fail_msg(PROV_ERR_CFM_FAILED); - atomic_set_bit(link.flags ,LINK_INVALID); goto done; } @@ -1014,8 +1029,6 @@ static void prov_random(const u8_t *data) if (prov_send(rnd)) { BT_ERR("Failed to send Provisioning Random"); - prov_send_fail_msg(PROV_ERR_RESOURCES); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -1023,7 +1036,6 @@ static void prov_random(const u8_t *data) link.prov_salt)) { BT_ERR("Failed to generate provisioning salt"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -1064,7 +1076,6 @@ static void prov_data(const u8_t *data) if (err) { BT_ERR("Unable to generate session key"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -1074,7 +1085,6 @@ static void prov_data(const u8_t *data) if (err) { BT_ERR("Unable to generate session nonce"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -1084,7 +1094,6 @@ static void prov_data(const u8_t *data) if (err) { BT_ERR("Unable to decrypt provisioning data"); prov_send_fail_msg(PROV_ERR_DECRYPT); - atomic_set_bit(link.flags ,LINK_INVALID); goto done; } @@ -1092,7 +1101,6 @@ static void prov_data(const u8_t *data) if (err) { BT_ERR("Unable to generate device key"); prov_send_fail_msg(PROV_ERR_UNEXP_ERR); - atomic_set_bit(link.flags, LINK_INVALID); goto done; } @@ -1107,7 +1115,10 @@ static void prov_data(const u8_t *data) net_idx, (unsigned) iv_index, addr); prov_buf_init(msg, PROV_COMPLETE); - prov_send(msg); + if (prov_send(msg)) { + BT_ERR("Failed to send Provisioning Complete"); + goto done; + } /* Ignore any further PDUs on this link */ link.expect = 0; @@ -1119,7 +1130,11 @@ static void prov_data(const u8_t *data) identity_enable = false; } - bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key); + err = bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key); + if (err) { + BT_ERR("Failed to provision (err %d)", err); + goto done; + } /* After PB-GATT provisioning we should start advertising * using Node Identity. @@ -1134,7 +1149,7 @@ done: static void prov_complete(const u8_t *data) { - BT_INFO(""); + BT_DBG(""); } static void prov_failed(const u8_t *data) @@ -1158,32 +1173,6 @@ static const struct { { prov_failed, 1 }, }; -static void close_link(u8_t err, u8_t reason) -{ -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - if (link.conn_handle != BLE_HS_CONN_HANDLE_NONE) { - bt_mesh_pb_gatt_close(link.conn_handle); - return; - } -#endif - -#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) - if (err) { - prov_send_fail_msg(err); - } - - link.rx.seg = 0; - bearer_ctl_send(LINK_CLOSE, &reason, sizeof(reason)); -#endif - - atomic_clear_bit(link.flags, LINK_ACTIVE); - - /* Disable Attention Timer if it was set */ - if (link.conf_inputs[0]) { - bt_mesh_attention(NULL, 0); - } -} - #if (MYNEWT_VAL(BLE_MESH_PB_ADV)) static void prov_retransmit(struct ble_npl_event *work) { @@ -1198,7 +1187,7 @@ static void prov_retransmit(struct ble_npl_event *work) if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) { BT_WARN("Giving up transaction"); - reset_link(); + reset_adv_link(); return; } @@ -1224,15 +1213,9 @@ static void prov_retransmit(struct ble_npl_event *work) } } -static void prot_tmo_link_close(struct ble_npl_event *ev) -{ - close_link(PROV_ERR_UNEXP_ERR, CLOSE_REASON_FAILED); - reset_link(); -} - static void link_open(struct prov_rx *rx, struct os_mbuf *buf) { - BT_INFO("link open: len %u", buf->om_len); + BT_DBG("link open: len %u", buf->om_len); if (buf->om_len < 16) { BT_ERR("Too short bearer open message (len %u)", buf->om_len); @@ -1272,14 +1255,14 @@ static void link_open(struct prov_rx *rx, struct os_mbuf *buf) static void link_ack(struct prov_rx *rx, struct os_mbuf *buf) { - BT_INFO("Link ack: len %u", buf->om_len); + BT_DBG("Link ack: len %u", buf->om_len); } static void link_close(struct prov_rx *rx, struct os_mbuf *buf) { - BT_INFO("Link close: len %u", buf->om_len); + BT_DBG("Link close: len %u", buf->om_len); - reset_link(); + reset_adv_link(); } static void gen_prov_ctl(struct prov_rx *rx, struct os_mbuf *buf) @@ -1317,11 +1300,12 @@ static void gen_prov_ctl(struct prov_rx *rx, struct os_mbuf *buf) static void prov_msg_recv(void) { - k_delayed_work_submit(&prot_timer, PROTOCOL_TIMEOUT); u8_t type = link.rx.buf->om_data[0]; BT_DBG("type 0x%02x len %u", type, link.rx.buf->om_len); + k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + if (!bt_mesh_fcs_check(link.rx.buf, link.rx.fcs)) { BT_ERR("Incorrect FCS"); return; @@ -1332,7 +1316,7 @@ static void prov_msg_recv(void) link.rx.id = 0; if (atomic_test_bit(link.flags, LINK_INVALID)) { - BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect); + BT_WARN("Unexpected msg 0x%02x on invalidated link", type); prov_send_fail_msg(PROV_ERR_UNEXP_PDU); return; } @@ -1340,14 +1324,12 @@ static void prov_msg_recv(void) if (type != PROV_FAILED && type != link.expect) { BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect); prov_send_fail_msg(PROV_ERR_UNEXP_PDU); - atomic_set_bit(link.flags, LINK_INVALID); return; } if (type >= ARRAY_SIZE(prov_handlers)) { BT_ERR("Unknown provisioning PDU type 0x%02x", type); prov_send_fail_msg(PROV_ERR_NVAL_PDU); - atomic_set_bit(link.flags, LINK_INVALID); return; } @@ -1355,7 +1337,6 @@ static void prov_msg_recv(void) BT_ERR("Invalid length %u for type 0x%02x", link.rx.buf->om_len, type); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } @@ -1383,18 +1364,16 @@ static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf) if (seg > link.rx.last_seg) { BT_ERR("Invalid segment index %u", seg); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } else if (seg == link.rx.last_seg) { u8_t expect_len; expect_len = (link.rx.buf->om_len - 20 - - (23 * (link.rx.last_seg - 1))); + ((link.rx.last_seg - 1) * 23)); if (expect_len != buf->om_len) { BT_ERR("Incorrect last seg len: %u != %u", expect_len, buf->om_len); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } } @@ -1452,7 +1431,6 @@ static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf) if (link.rx.buf->om_len < 1) { BT_ERR("Ignoring zero-length provisioning PDU"); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } @@ -1460,14 +1438,12 @@ static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf) BT_ERR("Too large provisioning PDU (%u bytes)", link.rx.buf->om_len); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } if (START_LAST_SEG(rx->gpc) > 0 && link.rx.buf->om_len <= 20) { BT_ERR("Too small total length for multi-segment PDU"); prov_send_fail_msg(PROV_ERR_NVAL_FMT); - atomic_set_bit(link.flags, LINK_INVALID); return; } @@ -1505,7 +1481,7 @@ static void gen_prov_recv(struct prov_rx *rx, struct os_mbuf *buf) return; } - BT_INFO("prov_action: %d", GPCF(rx->gpc)); + BT_DBG("prov_action: %d", GPCF(rx->gpc)); gen_prov[GPCF(rx->gpc)].func(rx, buf); } @@ -1559,7 +1535,6 @@ int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf) if (type != PROV_FAILED && type != link.expect) { BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect); prov_send_fail_msg(PROV_ERR_UNEXP_PDU); - atomic_set_bit(link.flags, LINK_INVALID); return -EINVAL; } @@ -1599,8 +1574,6 @@ int bt_mesh_pb_gatt_open(uint16_t conn_handle) int bt_mesh_pb_gatt_close(uint16_t conn_handle) { - bool pub_key; - BT_DBG("conn_handle %d", conn_handle); if (link.conn_handle != conn_handle) { @@ -1608,23 +1581,11 @@ int bt_mesh_pb_gatt_close(uint16_t conn_handle) return -ENOTCONN; } - /* Disable Attention Timer if it was set */ - if (link.conf_inputs[0]) { - bt_mesh_attention(NULL, 0); - } - if (prov->link_close) { prov->link_close(BT_MESH_PROV_GATT); } - pub_key = atomic_test_bit(link.flags, LOCAL_PUB_KEY); - memset(&link, 0, sizeof(link)); - - if (pub_key) { - atomic_set_bit(link.flags, LOCAL_PUB_KEY); - } - - return 0; + return reset_state(); } #endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ @@ -1638,57 +1599,54 @@ bool bt_prov_active(void) return atomic_test_bit(link.flags, LINK_ACTIVE); } +static void protocol_timeout(struct ble_npl_event *work) +{ + BT_DBG("Protocol timeout"); + +#if MYNEWT_VAL(BLE_MESH_PB_GATT) + if (link.conn_handle != BLE_HS_CONN_HANDLE_NONE) { + bt_mesh_pb_gatt_close(link.conn_handle); + return; + } +#endif + +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + u8_t reason = CLOSE_REASON_TIMEOUT; + + link.rx.seg = 0U; + bearer_ctl_send(LINK_CLOSE, &reason, sizeof(reason)); + + reset_state(); +#endif +} + int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) { - k_delayed_work_init(&prot_timer, prot_tmo_link_close); - static struct bt_pub_key_cb pub_key_cb = { - .func = pub_key_ready, - }; - int err; - -#if !(MYNEWT_VAL(BLE_MESH_PB_GATT)) - rx_buf = NET_BUF_SIMPLE(65); -#endif - -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - link.conn_handle = BLE_HS_CONN_HANDLE_NONE; -#endif - if (!prov_info) { BT_ERR("No provisioning context provided"); return -EINVAL; } - err = bt_pub_key_gen(&pub_key_cb); - if (err) { - BT_ERR("Failed to generate public key (%d)", err); - return err; - } + k_delayed_work_init(&link.prot_timer, protocol_timeout); prov = prov_info; - (void)prov_handlers; - -#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) +#if MYNEWT_VAL(BLE_MESH_PB_ADV) k_delayed_work_init(&link.tx.retransmit, prov_retransmit); - link.rx.prev_id = XACT_NVAL; +#endif -#if !(MYNEWT_VAL(BLE_MESH_PB_GATT)) + return reset_state(); +} + +void bt_mesh_prov_reset_link(void) +{ +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + link.rx.buf = bt_mesh_proxy_get_buf(); +#else net_buf_simple_init(rx_buf, 0); link.rx.buf = rx_buf; #endif - -#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ - - return 0; -} - -void bt_mesh_prov_reset_link(void) { -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - link.rx.buf = bt_mesh_proxy_get_buf(); -#else - net_buf_simple_init(rx_buf, 0); - link.rx.buf = rx_buf; #endif }