.release = single_release,
};
-static int own_address_type_set(void *data, u64 val)
+static ssize_t force_static_address_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
{
- struct hci_dev *hdev = data;
-
- if (val != 0 && val != 1)
- return -EINVAL;
-
- hci_dev_lock(hdev);
- hdev->own_addr_type = val;
- hci_dev_unlock(hdev);
+ struct hci_dev *hdev = file->private_data;
+ char buf[3];
- return 0;
+ buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ? 'Y': 'N';
+ buf[1] = '\n';
+ buf[2] = '\0';
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
-static int own_address_type_get(void *data, u64 *val)
+static ssize_t force_static_address_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
{
- struct hci_dev *hdev = data;
+ struct hci_dev *hdev = file->private_data;
+ char buf[32];
+ size_t buf_size = min(count, (sizeof(buf)-1));
+ bool enable;
- hci_dev_lock(hdev);
- *val = hdev->own_addr_type;
- hci_dev_unlock(hdev);
+ if (test_bit(HCI_UP, &hdev->flags))
+ return -EBUSY;
- return 0;
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ buf[buf_size] = '\0';
+ if (strtobool(buf, &enable))
+ return -EINVAL;
+
+ if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags))
+ return -EALREADY;
+
+ change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags);
+
+ return count;
}
-DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get,
- own_address_type_set, "%llu\n");
+static const struct file_operations force_static_address_fops = {
+ .open = simple_open,
+ .read = force_static_address_read,
+ .write = force_static_address_write,
+ .llseek = default_llseek,
+};
static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
{
hci_setup_link_policy(req);
if (lmp_le_capable(hdev)) {
- if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
- /* If the controller has a public BD_ADDR, then
- * by default use that one. If this is a LE only
- * controller without a public address, default
- * to the random address.
- */
- if (bacmp(&hdev->bdaddr, BDADDR_ANY))
- hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
- else
- hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
- }
+ /* If the controller has a public BD_ADDR, then by default
+ * use that one. If this is a LE only controller without
+ * a public address, default to the random address.
+ *
+ * For debugging purposes it is possible to force
+ * controllers with a public address to use the
+ * random address instead.
+ */
+ if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
+ !bacmp(&hdev->bdaddr, BDADDR_ANY))
+ hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
+ else
+ hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
hci_set_le_support(req);
}
}
if (lmp_le_capable(hdev)) {
+ debugfs_create_file("static_address", 0444, hdev->debugfs,
+ hdev, &static_address_fops);
+
+ /* For controllers with a public address, provide a debug
+ * option to force the usage of the configured static
+ * address. By default the public address is used.
+ */
+ if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+ debugfs_create_file("force_static_address", 0644,
+ hdev->debugfs, hdev,
+ &force_static_address_fops);
+
debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
&hdev->le_white_list_size);
- debugfs_create_file("static_address", 0444, hdev->debugfs,
- hdev, &static_address_fops);
- debugfs_create_file("own_address_type", 0644, hdev->debugfs,
- hdev, &own_address_type_fops);
debugfs_create_file("identity_resolving_keys", 0400,
hdev->debugfs, hdev,
&identity_resolving_keys_fops);