aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-02-18 14:41:34 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-02-18 14:48:55 -0500
commitf4a407bef20c0e63fcd910a9404418522abff4ab (patch)
tree8b799943596b78d9eb31e088d86f8c026cd558b8 /net/bluetooth/mgmt.c
parent387a33e304caeeabf0c2439607fa6e726666bdf0 (diff)
Bluetooth: Wait for SMP key distribution completion when pairing
When we initiate pairing through mgmt_pair_device the code has so far been waiting for a successful HCI Encrypt Change event in order to respond to the mgmt command. However, putting privacy into the play we actually want the key distribution to be complete before replying so that we can include the Identity Address in the mgmt response. This patch updates the various hci_conn callbacks for LE in mgmt.c to only respond in the case of failure, and adds a new mgmt_smp_complete function that the SMP code will call once key distribution has been completed. Since the smp_chan_destroy function that's used to indicate completion and clean up the SMP context can be called from various places, including outside of smp.c, the easiest way to track failure vs success is a new flag that we set once key distribution has been successfully completed. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 90aac905a98b..24a85fe76cd8 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2655,6 +2655,16 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
2655 mgmt_pending_remove(cmd); 2655 mgmt_pending_remove(cmd);
2656} 2656}
2657 2657
2658void mgmt_smp_complete(struct hci_conn *conn, bool complete)
2659{
2660 u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
2661 struct pending_cmd *cmd;
2662
2663 cmd = find_pairing(conn);
2664 if (cmd)
2665 pairing_complete(cmd, status);
2666}
2667
2658static void pairing_complete_cb(struct hci_conn *conn, u8 status) 2668static void pairing_complete_cb(struct hci_conn *conn, u8 status)
2659{ 2669{
2660 struct pending_cmd *cmd; 2670 struct pending_cmd *cmd;
@@ -2668,7 +2678,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
2668 pairing_complete(cmd, mgmt_status(status)); 2678 pairing_complete(cmd, mgmt_status(status));
2669} 2679}
2670 2680
2671static void le_connect_complete_cb(struct hci_conn *conn, u8 status) 2681static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
2672{ 2682{
2673 struct pending_cmd *cmd; 2683 struct pending_cmd *cmd;
2674 2684
@@ -2755,13 +2765,16 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
2755 } 2765 }
2756 2766
2757 /* For LE, just connecting isn't a proof that the pairing finished */ 2767 /* For LE, just connecting isn't a proof that the pairing finished */
2758 if (cp->addr.type == BDADDR_BREDR) 2768 if (cp->addr.type == BDADDR_BREDR) {
2759 conn->connect_cfm_cb = pairing_complete_cb; 2769 conn->connect_cfm_cb = pairing_complete_cb;
2760 else 2770 conn->security_cfm_cb = pairing_complete_cb;
2761 conn->connect_cfm_cb = le_connect_complete_cb; 2771 conn->disconn_cfm_cb = pairing_complete_cb;
2772 } else {
2773 conn->connect_cfm_cb = le_pairing_complete_cb;
2774 conn->security_cfm_cb = le_pairing_complete_cb;
2775 conn->disconn_cfm_cb = le_pairing_complete_cb;
2776 }
2762 2777
2763 conn->security_cfm_cb = pairing_complete_cb;
2764 conn->disconn_cfm_cb = pairing_complete_cb;
2765 conn->io_capability = cp->io_cap; 2778 conn->io_capability = cp->io_cap;
2766 cmd->user_data = conn; 2779 cmd->user_data = conn;
2767 2780