Bluetooth: Store address type with OOB data
authorJohan Hedberg <johan.hedberg@intel.com>
Sun, 26 Oct 2014 19:46:09 +0000 (20:46 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 3 Dec 2014 15:51:21 +0000 (16:51 +0100)
To be able to support OOB data for LE pairing we need to store the
address type of the remote device. This patch extends the relevant
functions and data types with a bdaddr_type variable.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index 3e89ece7503975054493f257e499419ab74dbcfb..1dae7001fc3196923bc612809093bbdf99837646 100644 (file)
@@ -140,6 +140,7 @@ struct link_key {
 struct oob_data {
        struct list_head list;
        bdaddr_t bdaddr;
+       u8 bdaddr_type;
        u8 hash192[16];
        u8 rand192[16];
        u8 hash256[16];
@@ -942,11 +943,12 @@ void hci_smp_irks_clear(struct hci_dev *hdev);
 
 void hci_remote_oob_data_clear(struct hci_dev *hdev);
 struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
-                                         bdaddr_t *bdaddr);
+                                         bdaddr_t *bdaddr, u8 bdaddr_type);
 int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
-                           u8 *hash192, u8 *rand192,
+                           u8 bdaddr_type, u8 *hash192, u8 *rand192,
                            u8 *hash256, u8 *rand256);
-int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
+                              u8 bdaddr_type);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
index 967fbfe80f1fa7b9cdd6fe3c70603585575375cf..c8123f04a33c571dc042aff668d06a8272754fd7 100644 (file)
@@ -2160,7 +2160,7 @@ u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
 
        BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
 
-       hci_remove_remote_oob_data(hdev, &data->bdaddr);
+       hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
 
        if (!data->ssp_mode)
                flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
@@ -3479,26 +3479,31 @@ static void hci_cmd_timeout(struct work_struct *work)
 }
 
 struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
-                                         bdaddr_t *bdaddr)
+                                         bdaddr_t *bdaddr, u8 bdaddr_type)
 {
        struct oob_data *data;
 
-       list_for_each_entry(data, &hdev->remote_oob_data, list)
-               if (bacmp(bdaddr, &data->bdaddr) == 0)
-                       return data;
+       list_for_each_entry(data, &hdev->remote_oob_data, list) {
+               if (bacmp(bdaddr, &data->bdaddr) != 0)
+                       continue;
+               if (data->bdaddr_type != bdaddr_type)
+                       continue;
+               return data;
+       }
 
        return NULL;
 }
 
-int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
+                              u8 bdaddr_type)
 {
        struct oob_data *data;
 
-       data = hci_find_remote_oob_data(hdev, bdaddr);
+       data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
        if (!data)
                return -ENOENT;
 
-       BT_DBG("%s removing %pMR", hdev->name, bdaddr);
+       BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
 
        list_del(&data->list);
        kfree(data);
@@ -3517,18 +3522,19 @@ void hci_remote_oob_data_clear(struct hci_dev *hdev)
 }
 
 int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
-                           u8 *hash192, u8 *rand192,
+                           u8 bdaddr_type, u8 *hash192, u8 *rand192,
                            u8 *hash256, u8 *rand256)
 {
        struct oob_data *data;
 
-       data = hci_find_remote_oob_data(hdev, bdaddr);
+       data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
        if (!data) {
                data = kmalloc(sizeof(*data), GFP_KERNEL);
                if (!data)
                        return -ENOMEM;
 
                bacpy(&data->bdaddr, bdaddr);
+               data->bdaddr_type = bdaddr_type;
                list_add(&data->list, &hdev->remote_oob_data);
        }
 
index c3d6390e3b7b6ae546a6eae6797f0f4f0543841b..f4e2a61bb6aa20568e270d4265dcd0864f5ad742 100644 (file)
@@ -3773,7 +3773,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
                cp.authentication = conn->auth_type;
 
-               if (hci_find_remote_oob_data(hdev, &conn->dst) &&
+               if (hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR) &&
                    (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
                        cp.oob_data = 0x01;
                else
@@ -4028,7 +4028,7 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
        if (!test_bit(HCI_MGMT, &hdev->dev_flags))
                goto unlock;
 
-       data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
+       data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
        if (data) {
                if (bredr_sc_enabled(hdev)) {
                        struct hci_cp_remote_oob_ext_data_reply cp;
index 0d92ba99ca935c4c5cea7ee2811175e3d1c31a97..57de9f7222aa20939b4a82b4985ecc478a6709fe 100644 (file)
@@ -3599,8 +3599,8 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
                }
 
                err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr,
-                                             cp->hash, cp->rand,
-                                             NULL, NULL);
+                                             cp->addr.type, cp->hash,
+                                             cp->rand, NULL, NULL);
                if (err < 0)
                        status = MGMT_STATUS_FAILED;
                else
@@ -3621,8 +3621,9 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
                }
 
                err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr,
-                                             cp->hash192, cp->rand192,
-                                             cp->hash256, cp->rand256);
+                                             cp->addr.type, cp->hash192,
+                                             cp->rand192, cp->hash256,
+                                             cp->rand256);
                if (err < 0)
                        status = MGMT_STATUS_FAILED;
                else
@@ -3663,7 +3664,7 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
                goto done;
        }
 
-       err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr);
+       err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr, cp->addr.type);
        if (err < 0)
                status = MGMT_STATUS_INVALID_PARAMS;
        else