From 1fb68828eff81d7fa0413db9633b86a422015037 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Wed, 3 Jul 2019 13:46:03 +0200 Subject: [PATCH] Bluetooth: SMP: Add pairing failed reason Forward the pairing failed SMP status code to the application Signed-off-by: Joakim Andersson --- include/bluetooth/conn.h | 33 +++++++++++++++++- .../bluetooth/peripheral_sc_only/src/main.c | 4 +-- .../boards/reel_board/mesh_badge/src/main.c | 4 +-- subsys/bluetooth/host/smp.c | 34 +++++++++++++++++-- subsys/bluetooth/shell/bt.c | 6 ++-- 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/include/bluetooth/conn.h b/include/bluetooth/conn.h index 56186daac70..b9ba626c21a 100644 --- a/include/bluetooth/conn.h +++ b/include/bluetooth/conn.h @@ -323,6 +323,35 @@ int bt_conn_security(struct bt_conn *conn, bt_security_t sec); */ u8_t bt_conn_enc_key_size(struct bt_conn *conn); +enum bt_security_err { + /** Security procedure successful. */ + BT_SECURITY_ERR_SUCCESS, + + /** Authentication failed. */ + BT_SECURITY_ERR_AUTHENTICATION_FAIL, + + /** PIN or encryption key is missing. */ + BT_SECURITY_ERR_PIN_OR_KEY_MISSING, + + /** OOB data is not available. */ + BT_SECURITY_ERR_OOB_NOT_AVAILABLE, + + /** The requested security level could not be reached. */ + BT_SECURITY_ERR_AUTHENTICATION_REQUIREMENT, + + /** Pairing is not supported */ + BT_SECURITY_ERR_PAIR_NOT_SUPPORTED, + + /** Pairing is not allowed. */ + BT_SECURITY_ERR_PAIR_NOT_ALLOWED, + + /** Invalid parameters. */ + BT_SECURITY_ERR_INVALID_PARAM, + + /** Pairing failed but the exact reason could not be specified. */ + BT_SECURITY_ERR_UNSPECIFIED, +}; + /** @brief Connection callback structure. * * This structure is used for tracking the state of a connection. @@ -698,8 +727,10 @@ struct bt_conn_auth_cb { /** @brief notify that pairing process has failed. * * @param conn Connection object. + * @param reason Pairing failed reason */ - void (*pairing_failed)(struct bt_conn *conn); + void (*pairing_failed)(struct bt_conn *conn, + enum bt_security_err reason); }; /** @brief Register authentication callbacks. diff --git a/samples/bluetooth/peripheral_sc_only/src/main.c b/samples/bluetooth/peripheral_sc_only/src/main.c index 1e7dbe8e22c..aaaa65637d6 100644 --- a/samples/bluetooth/peripheral_sc_only/src/main.c +++ b/samples/bluetooth/peripheral_sc_only/src/main.c @@ -102,9 +102,9 @@ static void pairing_complete(struct bt_conn *conn, bool bonded) printk("Pairing Complete\n"); } -static void pairing_failed(struct bt_conn *conn) +static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason) { - printk("Pairing Failed. Disconnecting.\n"); + printk("Pairing Failed (%d). Disconnecting.\n", reason); bt_conn_disconnect(conn, BT_HCI_ERR_AUTHENTICATION_FAIL); } diff --git a/samples/boards/reel_board/mesh_badge/src/main.c b/samples/boards/reel_board/mesh_badge/src/main.c index 7f52a54510d..19c78ac763f 100644 --- a/samples/boards/reel_board/mesh_badge/src/main.c +++ b/samples/boards/reel_board/mesh_badge/src/main.c @@ -106,9 +106,9 @@ static void pairing_complete(struct bt_conn *conn, bool bonded) board_show_text("Pairing Complete", false, K_SECONDS(2)); } -static void pairing_failed(struct bt_conn *conn) +static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason) { - printk("Pairing Failed\n"); + printk("Pairing Failed (%d)\n", reason); board_show_text("Pairing Failed", false, K_SECONDS(2)); } diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index b5da4a404da..b9601dacea5 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -330,6 +330,34 @@ static u8_t get_pair_method(struct bt_smp *smp, u8_t remote_io) return gen_method_sc[remote_io][get_io_capa()]; } +static enum bt_security_err auth_err_get(u8_t smp_err) +{ + switch (smp_err) { + case BT_SMP_ERR_PASSKEY_ENTRY_FAILED: + case BT_SMP_ERR_DHKEY_CHECK_FAILED: + case BT_SMP_ERR_NUMERIC_COMP_FAILED: + case BT_SMP_ERR_CONFIRM_FAILED: + return BT_SECURITY_ERR_AUTHENTICATION_FAIL; + case BT_SMP_ERR_OOB_NOT_AVAIL: + return BT_SECURITY_ERR_OOB_NOT_AVAILABLE; + case BT_SMP_ERR_AUTH_REQUIREMENTS: + case BT_SMP_ERR_ENC_KEY_SIZE: + return BT_SECURITY_ERR_AUTHENTICATION_REQUIREMENT; + case BT_SMP_ERR_PAIRING_NOTSUPP: + case BT_SMP_ERR_CMD_NOTSUPP: + return BT_SECURITY_ERR_PAIR_NOT_SUPPORTED; + case BT_SMP_ERR_REPEATED_ATTEMPTS: + case BT_SMP_ERR_BREDR_PAIRING_IN_PROGRESS: + case BT_SMP_ERR_CROSS_TRANSP_NOT_ALLOWED: + return BT_SECURITY_ERR_PAIR_NOT_ALLOWED; + case BT_SMP_ERR_INVALID_PARAMS: + return BT_SECURITY_ERR_INVALID_PARAM; + case BT_SMP_ERR_UNSPECIFIED: + default: + return BT_SECURITY_ERR_UNSPECIFIED; + } +} + static struct net_buf *smp_create_pdu(struct bt_conn *conn, u8_t op, size_t len) { @@ -756,7 +784,8 @@ static void smp_pairing_br_complete(struct bt_smp_br *smp, u8_t status) } if (bt_auth && bt_auth->pairing_failed) { - bt_auth->pairing_failed(smp->chan.chan.conn); + bt_auth->pairing_failed(smp->chan.chan.conn, + auth_err_get(status)); } } else { bool bond_flag = atomic_test_bit(smp->flags, SMP_FLAG_BOND); @@ -1556,7 +1585,8 @@ static void smp_pairing_complete(struct bt_smp *smp, u8_t status) bond_flag); } } else if (bt_auth && bt_auth->pairing_failed) { - bt_auth->pairing_failed(smp->chan.chan.conn); + bt_auth->pairing_failed(smp->chan.chan.conn, + auth_err_get(status)); } smp_reset(smp); diff --git a/subsys/bluetooth/shell/bt.c b/subsys/bluetooth/shell/bt.c index bd788f9c46f..e34e0301879 100644 --- a/subsys/bluetooth/shell/bt.c +++ b/subsys/bluetooth/shell/bt.c @@ -1239,13 +1239,15 @@ static void auth_pairing_complete(struct bt_conn *conn, bool bonded) addr); } -static void auth_pairing_failed(struct bt_conn *conn) +static void auth_pairing_failed(struct bt_conn *conn, + enum bt_security_err reason) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); - shell_print(ctx_shell, "Pairing failed with %s", addr); + shell_print(ctx_shell, "Pairing failed with %s reason %d", addr, + reason); } #if defined(CONFIG_BT_BREDR)