Bluetooth: Provide option for changing LE advertising channel map
authorMarcel Holtmann <marcel@holtmann.org>
Thu, 20 Feb 2014 19:55:56 +0000 (11:55 -0800)
committerJohan Hedberg <johan.hedberg@intel.com>
Fri, 21 Feb 2014 04:20:59 +0000 (06:20 +0200)
For testing purposes it is useful to provide an option to change the
advertising channel map. So add a debugfs option to allow this.

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

index 3a8e22e9b25d48fbab72332616cb9cda42c8d282..c0fcc041fbb5e36b70306a4872de05207ad193c1 100644 (file)
@@ -178,6 +178,7 @@ struct hci_dev {
        __u16           page_scan_interval;
        __u16           page_scan_window;
        __u8            page_scan_type;
+       __u8            le_adv_channel_map;
        __u16           le_scan_interval;
        __u16           le_scan_window;
        __u16           le_conn_min_interval;
index 877330b4876faef29aa988b4b8340b3ae0572ef6..67192867c998f1fc1bf1704dd67ade368dc2f56e 100644 (file)
@@ -757,6 +757,34 @@ static int conn_max_interval_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
                        conn_max_interval_set, "%llu\n");
 
+static int adv_channel_map_set(void *data, u64 val)
+{
+       struct hci_dev *hdev = data;
+
+       if (val < 0x01 || val > 0x07)
+               return -EINVAL;
+
+       hci_dev_lock(hdev);
+       hdev->le_adv_channel_map = val;
+       hci_dev_unlock(hdev);
+
+       return 0;
+}
+
+static int adv_channel_map_get(void *data, u64 *val)
+{
+       struct hci_dev *hdev = data;
+
+       hci_dev_lock(hdev);
+       *val = hdev->le_adv_channel_map;
+       hci_dev_unlock(hdev);
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
+                       adv_channel_map_set, "%llu\n");
+
 static ssize_t lowpan_read(struct file *file, char __user *user_buf,
                           size_t count, loff_t *ppos)
 {
@@ -1605,6 +1633,8 @@ static int __hci_init(struct hci_dev *hdev)
                                    hdev, &conn_min_interval_fops);
                debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
                                    hdev, &conn_max_interval_fops);
+               debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
+                                   hdev, &adv_channel_map_fops);
                debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
                                    &lowpan_debugfs_fops);
        }
@@ -3264,6 +3294,7 @@ struct hci_dev *hci_alloc_dev(void)
        hdev->sniff_max_interval = 800;
        hdev->sniff_min_interval = 80;
 
+       hdev->le_adv_channel_map = 0x07;
        hdev->le_scan_interval = 0x0060;
        hdev->le_scan_window = 0x0030;
        hdev->le_conn_min_interval = 0x0028;
index 5f5e388716ec0619be0e11c4ca5fed9e8f361f6f..12fa6399c796fed1afbf6344fc1d0899731a5840 100644 (file)
@@ -1374,7 +1374,7 @@ static void enable_advertising(struct hci_request *req)
        cp.max_interval = __constant_cpu_to_le16(0x0800);
        cp.type = get_adv_type(hdev);
        cp.own_address_type = hdev->own_addr_type;
-       cp.channel_map = 0x07;
+       cp.channel_map = hdev->le_adv_channel_map;
 
        hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);