aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_request.c
diff options
context:
space:
mode:
authorJaganath Kanakkassery <jaganath.k.os@gmail.com>2018-07-06 07:35:28 -0400
committerMarcel Holtmann <marcel@holtmann.org>2018-07-06 16:41:17 -0400
commita2344b9e3a8c5c2064306b0d99b0e9a6c4813c08 (patch)
tree640724bb9bb1f691efd66d60f8709a7b0c3d68d2 /net/bluetooth/hci_request.c
parent3baef810462746cd5a085c1e1416829d2af2622d (diff)
Bluetooth: Use extended scanning if controller supports
This implements Set extended scan param and set extended scan enable commands and use it for start LE scan based on controller support. The new features added in these commands are setting of new PHY for scanning and setting of scan duration. Both features are disabled for now, meaning only 1M PHY is set and scan duration is set to 0 which means that scanning will be done untill scan disable is called. < HCI Command: LE Set Extended Scan Parameters (0x08|0x0041) plen 8 Own address type: Random (0x01) Filter policy: Accept all advertisement (0x00) PHYs: 0x01 Entry 0: LE 1M Type: Active (0x01) Interval: 11.250 msec (0x0012) Window: 11.250 msec (0x0012) > HCI Event: Command Complete (0x0e) plen 4 LE Set Extended Scan Parameters (0x08|0x0041) ncmd 1 Status: Success (0x00) < HCI Command: LE Set Extended Scan Enable (0x08|0x0042) plen 6 Extended scan: Enabled (0x01) Filter duplicates: Enabled (0x01) Duration: 0 msec (0x0000) Period: 0.00 sec (0x0000) > HCI Event: Command Complete (0x0e) plen 4 LE Set Extended Scan Enable (0x08|0x0042) ncmd 2 Status: Success (0x00) Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_request.c')
-rw-r--r--net/bluetooth/hci_request.c110
1 files changed, 85 insertions, 25 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 76dcc3f14cea..faf7c711234c 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -647,11 +647,22 @@ void __hci_req_update_eir(struct hci_request *req)
647 647
648void hci_req_add_le_scan_disable(struct hci_request *req) 648void hci_req_add_le_scan_disable(struct hci_request *req)
649{ 649{
650 struct hci_cp_le_set_scan_enable cp; 650 struct hci_dev *hdev = req->hdev;
651 651
652 memset(&cp, 0, sizeof(cp)); 652 if (use_ext_scan(hdev)) {
653 cp.enable = LE_SCAN_DISABLE; 653 struct hci_cp_le_set_ext_scan_enable cp;
654 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 654
655 memset(&cp, 0, sizeof(cp));
656 cp.enable = LE_SCAN_DISABLE;
657 hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_ENABLE, sizeof(cp),
658 &cp);
659 } else {
660 struct hci_cp_le_set_scan_enable cp;
661
662 memset(&cp, 0, sizeof(cp));
663 cp.enable = LE_SCAN_DISABLE;
664 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
665 }
655} 666}
656 667
657static void add_to_white_list(struct hci_request *req, 668static void add_to_white_list(struct hci_request *req,
@@ -770,23 +781,60 @@ static bool scan_use_rpa(struct hci_dev *hdev)
770static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval, 781static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
771 u16 window, u8 own_addr_type, u8 filter_policy) 782 u16 window, u8 own_addr_type, u8 filter_policy)
772{ 783{
773 struct hci_cp_le_set_scan_param param_cp; 784 struct hci_dev *hdev = req->hdev;
774 struct hci_cp_le_set_scan_enable enable_cp;
775
776 memset(&param_cp, 0, sizeof(param_cp));
777 param_cp.type = type;
778 param_cp.interval = cpu_to_le16(interval);
779 param_cp.window = cpu_to_le16(window);
780 param_cp.own_address_type = own_addr_type;
781 param_cp.filter_policy = filter_policy;
782 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
783 &param_cp);
784 785
785 memset(&enable_cp, 0, sizeof(enable_cp)); 786 /* Use ext scanning if set ext scan param and ext scan enable is
786 enable_cp.enable = LE_SCAN_ENABLE; 787 * supported
787 enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; 788 */
788 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), 789 if (use_ext_scan(hdev)) {
789 &enable_cp); 790 struct hci_cp_le_set_ext_scan_params *ext_param_cp;
791 struct hci_cp_le_set_ext_scan_enable ext_enable_cp;
792 struct hci_cp_le_scan_phy_params *phy_params;
793 /* Ony single PHY (1M) is supported as of now */
794 u8 data[sizeof(*ext_param_cp) + sizeof(*phy_params) * 1];
795
796 ext_param_cp = (void *)data;
797 phy_params = (void *)ext_param_cp->data;
798
799 memset(ext_param_cp, 0, sizeof(*ext_param_cp));
800 ext_param_cp->own_addr_type = own_addr_type;
801 ext_param_cp->filter_policy = filter_policy;
802 ext_param_cp->scanning_phys = LE_SCAN_PHY_1M;
803
804 memset(phy_params, 0, sizeof(*phy_params));
805 phy_params->type = type;
806 phy_params->interval = cpu_to_le16(interval);
807 phy_params->window = cpu_to_le16(window);
808
809 hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_PARAMS,
810 sizeof(*ext_param_cp) + sizeof(*phy_params),
811 ext_param_cp);
812
813 memset(&ext_enable_cp, 0, sizeof(ext_enable_cp));
814 ext_enable_cp.enable = LE_SCAN_ENABLE;
815 ext_enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
816
817 hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_ENABLE,
818 sizeof(ext_enable_cp), &ext_enable_cp);
819 } else {
820 struct hci_cp_le_set_scan_param param_cp;
821 struct hci_cp_le_set_scan_enable enable_cp;
822
823 memset(&param_cp, 0, sizeof(param_cp));
824 param_cp.type = type;
825 param_cp.interval = cpu_to_le16(interval);
826 param_cp.window = cpu_to_le16(window);
827 param_cp.own_address_type = own_addr_type;
828 param_cp.filter_policy = filter_policy;
829 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
830 &param_cp);
831
832 memset(&enable_cp, 0, sizeof(enable_cp));
833 enable_cp.enable = LE_SCAN_ENABLE;
834 enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
835 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
836 &enable_cp);
837 }
790} 838}
791 839
792void hci_req_add_le_passive_scan(struct hci_request *req) 840void hci_req_add_le_passive_scan(struct hci_request *req)
@@ -1948,7 +1996,6 @@ discov_stopped:
1948static int le_scan_restart(struct hci_request *req, unsigned long opt) 1996static int le_scan_restart(struct hci_request *req, unsigned long opt)
1949{ 1997{
1950 struct hci_dev *hdev = req->hdev; 1998 struct hci_dev *hdev = req->hdev;
1951 struct hci_cp_le_set_scan_enable cp;
1952 1999
1953 /* If controller is not scanning we are done. */ 2000 /* If controller is not scanning we are done. */
1954 if (!hci_dev_test_flag(hdev, HCI_LE_SCAN)) 2001 if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
@@ -1956,10 +2003,23 @@ static int le_scan_restart(struct hci_request *req, unsigned long opt)
1956 2003
1957 hci_req_add_le_scan_disable(req); 2004 hci_req_add_le_scan_disable(req);
1958 2005
1959 memset(&cp, 0, sizeof(cp)); 2006 if (use_ext_scan(hdev)) {
1960 cp.enable = LE_SCAN_ENABLE; 2007 struct hci_cp_le_set_ext_scan_enable ext_enable_cp;
1961 cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; 2008
1962 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 2009 memset(&ext_enable_cp, 0, sizeof(ext_enable_cp));
2010 ext_enable_cp.enable = LE_SCAN_ENABLE;
2011 ext_enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
2012
2013 hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_ENABLE,
2014 sizeof(ext_enable_cp), &ext_enable_cp);
2015 } else {
2016 struct hci_cp_le_set_scan_enable cp;
2017
2018 memset(&cp, 0, sizeof(cp));
2019 cp.enable = LE_SCAN_ENABLE;
2020 cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
2021 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
2022 }
1963 2023
1964 return 0; 2024 return 0;
1965} 2025}