mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-30 17:23:31 +00:00
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
This commit is contained in:
+160
-202
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user