Bluetooth: Add add/remove_remote_oob_data management commands
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / bluetooth / hci_core.c
index c20cbe5ff6db7cff65365d4e786d21d96706055b..675f0a1832eedf849853369f58c1b339ca51a01f 100644 (file)
@@ -1076,6 +1076,70 @@ static void hci_cmd_timer(unsigned long arg)
        tasklet_schedule(&hdev->cmd_task);
 }
 
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+                                                       bdaddr_t *bdaddr)
+{
+       struct oob_data *data;
+
+       list_for_each_entry(data, &hdev->remote_oob_data, list)
+               if (bacmp(bdaddr, &data->bdaddr) == 0)
+                       return data;
+
+       return NULL;
+}
+
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+       struct oob_data *data;
+
+       data = hci_find_remote_oob_data(hdev, bdaddr);
+       if (!data)
+               return -ENOENT;
+
+       BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+
+       list_del(&data->list);
+       kfree(data);
+
+       return 0;
+}
+
+int hci_remote_oob_data_clear(struct hci_dev *hdev)
+{
+       struct oob_data *data, *n;
+
+       list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
+               list_del(&data->list);
+               kfree(data);
+       }
+
+       return 0;
+}
+
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+                                                               u8 *randomizer)
+{
+       struct oob_data *data;
+
+       data = hci_find_remote_oob_data(hdev, bdaddr);
+
+       if (!data) {
+               data = kmalloc(sizeof(*data), GFP_ATOMIC);
+               if (!data)
+                       return -ENOMEM;
+
+               bacpy(&data->bdaddr, bdaddr);
+               list_add(&data->list, &hdev->remote_oob_data);
+       }
+
+       memcpy(data->hash, hash, sizeof(data->hash));
+       memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
+
+       BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
+
+       return 0;
+}
+
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
@@ -1140,6 +1204,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
        INIT_LIST_HEAD(&hdev->link_keys);
 
+       INIT_LIST_HEAD(&hdev->remote_oob_data);
+
        INIT_WORK(&hdev->power_on, hci_power_on);
        INIT_WORK(&hdev->power_off, hci_power_off);
        setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1219,6 +1285,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
        hci_blacklist_clear(hdev);
        hci_uuids_clear(hdev);
        hci_link_keys_clear(hdev);
+       hci_remote_oob_data_clear(hdev);
        hci_dev_unlock_bh(hdev);
 
        __hci_dev_put(hdev);