Bluetooth: Mesh: Fix send input_complete before public key

According Mesh Profile Spec 5.4.2.4 Authentication, if device
use Input OOB Authentication method, should send input complete
pub after local public key has been acked.

`bt_mesh_input_string` or `bt_mesh_input_number` directly send
`input_complete`, however does not check whether the pub key has
been sent.

Mesh Provisioning timeout set to `60` seconds, so even this
probability is extremely low, it does not mean that there is no
such probability.

Signed-off-by: Lingao Meng <mengabc1086@gmail.com>
This commit is contained in:
Lingao Meng 2020-09-18 15:54:42 +08:00 committed by Johan Hedberg
commit 4cc8cb1c15

View file

@ -73,12 +73,14 @@
#define PROV_ALG_P256 0x00
enum {
WAIT_PUB_KEY, /* Waiting for local PubKey to be generated */
LINK_ACTIVE, /* Link has been opened */
WAIT_NUMBER, /* Waiting for number input from user */
WAIT_STRING, /* Waiting for string input from user */
NOTIFY_INPUT_COMPLETE, /* Notify that input has been completed. */
PROVISIONER, /* The link was opened as provisioner */
WAIT_PUB_KEY, /* Waiting for local PubKey to be generated */
LINK_ACTIVE, /* Link has been opened */
WAIT_NUMBER, /* Waiting for number input from user */
WAIT_STRING, /* Waiting for string input from user */
NOTIFY_INPUT_COMPLETE, /* Notify that input has been completed. */
PROVISIONER, /* The link was opened as provisioner */
PUB_KEY_SENT, /* Public key has been sent */
INPUT_COMPLETE, /* Device input completed */
NUM_FLAGS,
};
@ -586,6 +588,15 @@ static void send_input_complete(void)
link.expect = PROV_CONFIRM;
}
static void input_complete(void)
{
if (atomic_test_bit(link.flags, PUB_KEY_SENT)) {
send_input_complete();
} else {
atomic_set_bit(link.flags, INPUT_COMPLETE);
}
}
int bt_mesh_input_number(uint32_t num)
{
BT_DBG("%u", num);
@ -596,7 +607,7 @@ int bt_mesh_input_number(uint32_t num)
sys_put_be32(num, &link.auth[12]);
send_input_complete();
input_complete();
return 0;
}
@ -611,11 +622,21 @@ int bt_mesh_input_string(const char *str)
strncpy((char *)link.auth, str, prov->input_size);
send_input_complete();
input_complete();
return 0;
}
static void public_key_sent(int err, void *cb_data)
{
atomic_set_bit(link.flags, PUB_KEY_SENT);
if (atomic_test_bit(link.flags, INPUT_COMPLETE)) {
send_input_complete();
return;
}
}
static void send_pub_key(void)
{
PROV_BUF(buf, 65);
@ -644,7 +665,7 @@ static void send_pub_key(void)
memcpy(&link.conf_inputs[81], &buf.data[1], 64);
}
if (prov_send(&buf, NULL)) {
if (prov_send(&buf, public_key_sent)) {
BT_ERR("Failed to send Public Key");
return;
}