Bluetooth: Add support for utilizing Fast Advertising Interval
authorSpoorthi Ravishankar Koppad <spoorthix.k@intel.com>
Mon, 15 Jul 2019 11:35:22 +0000 (17:05 +0530)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 5 Sep 2019 15:27:21 +0000 (17:27 +0200)
Changes made to add support for fast advertising interval
as per core 4.1 specification, section 9.3.11.2.

A peripheral device entering any of the following GAP modes and
sending either non-connectable advertising events or scannable
undirected advertising events should use adv_fast_interval2
(100ms - 150ms) for adv_fast_period(30s).

         - Non-Discoverable Mode
         - Non-Connectable Mode
         - Limited Discoverable Mode
         - General Discoverable Mode

Signed-off-by: Spoorthi Ravishankar Koppad <spoorthix.k@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_request.c

index ffc95b3..b689ace 100644 (file)
@@ -1517,6 +1517,8 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);
 #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04
 #define DISCOV_BREDR_INQUIRY_LEN       0x08
 #define DISCOV_LE_RESTART_DELAY                msecs_to_jiffies(200)   /* msec */
+#define DISCOV_LE_FAST_ADV_INT_MIN     100     /* msec */
+#define DISCOV_LE_FAST_ADV_INT_MAX     150     /* msec */
 
 void mgmt_fill_version_info(void *ver);
 int mgmt_new_settings(struct hci_dev *hdev);
index 621f1a9..7f6a581 100644 (file)
@@ -1054,6 +1054,7 @@ void __hci_req_enable_advertising(struct hci_request *req)
        struct hci_cp_le_set_adv_param cp;
        u8 own_addr_type, enable = 0x01;
        bool connectable;
+       u16 adv_min_interval, adv_max_interval;
        u32 flags;
 
        flags = get_adv_instance_flags(hdev, hdev->cur_adv_instance);
@@ -1087,16 +1088,30 @@ void __hci_req_enable_advertising(struct hci_request *req)
                return;
 
        memset(&cp, 0, sizeof(cp));
-       cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval);
-       cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval);
 
-       if (connectable)
+       if (connectable) {
                cp.type = LE_ADV_IND;
-       else if (get_cur_adv_instance_scan_rsp_len(hdev))
-               cp.type = LE_ADV_SCAN_IND;
-       else
-               cp.type = LE_ADV_NONCONN_IND;
 
+               adv_min_interval = hdev->le_adv_min_interval;
+               adv_max_interval = hdev->le_adv_max_interval;
+       } else {
+               if (get_cur_adv_instance_scan_rsp_len(hdev))
+                       cp.type = LE_ADV_SCAN_IND;
+               else
+                       cp.type = LE_ADV_NONCONN_IND;
+
+               if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE) ||
+                   hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
+                       adv_min_interval = DISCOV_LE_FAST_ADV_INT_MIN;
+                       adv_max_interval = DISCOV_LE_FAST_ADV_INT_MAX;
+               } else {
+                       adv_min_interval = hdev->le_adv_min_interval;
+                       adv_max_interval = hdev->le_adv_max_interval;
+               }
+       }
+
+       cp.min_interval = cpu_to_le16(adv_min_interval);
+       cp.max_interval = cpu_to_le16(adv_max_interval);
        cp.own_address_type = own_addr_type;
        cp.channel_map = hdev->le_adv_channel_map;