OSDN Git Service

Use extended set scan enable/parameters when available
authorJakub Pawlowski <jpawlowski@google.com>
Fri, 2 Dec 2016 19:34:06 +0000 (11:34 -0800)
committerJakub Pawlowski <jpawlowski@google.com>
Mon, 19 Dec 2016 22:24:37 +0000 (14:24 -0800)
When LE Advertising Extension is available on the controller we must use
both extended advertising and scanning commands. Otherwise, according to
the spec, controller will return error.

This patch makes sure that proper avaliable HCI calls are made.

Bug: 30622771
Test: sl4a ConcurrentBleAdvertisingTest as scanner
Change-Id: I6906c381f0f758bd24b592390a4ef46e7fae36ed

stack/btm/btm_ble_bgconn.cc
stack/btm/btm_ble_gap.cc
stack/btm/btm_ble_int.h
stack/btm/btm_inq.cc
stack/hcic/hciblecmds.cc
stack/include/hcidefs.h
stack/include/hcimsgs.h

index ec3b4f8..76d061c 100644 (file)
@@ -114,7 +114,7 @@ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) {
                          : p_inq->scan_type;
 
   if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) {
-    btsnd_hcic_ble_set_scan_params(
+    btm_send_hci_set_scan_params(
         p_inq->scan_type, (uint16_t)scan_interval, (uint16_t)scan_window,
         btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, scan_policy);
   } else {
index 8e80b5c..3d9455c 100644 (file)
@@ -449,7 +449,7 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration,
 #endif
 
       if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) {
-        btsnd_hcic_ble_set_scan_params(
+        btm_send_hci_set_scan_params(
             p_inq->scan_type, (uint16_t)scan_interval, (uint16_t)scan_window,
             btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, BTM_BLE_DEFAULT_SFP);
       } else {
@@ -1390,6 +1390,32 @@ tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode) {
   return status;
 }
 
+void btm_send_hci_scan_enable(uint8_t enable, uint8_t filter_duplicates) {
+  if (controller_get_interface()->supports_ble_extended_advertising()) {
+    btsnd_hcic_ble_set_extended_scan_enable(enable, filter_duplicates, 0x0000,
+                                            0x0000);
+  } else {
+    btsnd_hcic_ble_set_scan_enable(enable, filter_duplicates);
+  }
+}
+
+void btm_send_hci_set_scan_params(uint8_t scan_type, uint16_t scan_int,
+                                  uint16_t scan_win, uint8_t addr_type_own,
+                                  uint8_t scan_filter_policy) {
+  if (controller_get_interface()->supports_ble_extended_advertising()) {
+    scanning_phy_cfg phy_cfg;
+    phy_cfg.scan_type = scan_type;
+    phy_cfg.scan_int = scan_int;
+    phy_cfg.scan_win = scan_win;
+
+    btsnd_hcic_ble_set_extended_scan_params(addr_type_own, scan_filter_policy,
+                                            1, &phy_cfg);
+  } else {
+    btsnd_hcic_ble_set_scan_params(scan_type, scan_int, scan_win, addr_type_own,
+                                   scan_filter_policy);
+  }
+}
+
 /*******************************************************************************
  *
  * Function         btm_ble_start_inquiry
@@ -1427,7 +1453,7 @@ tBTM_STATUS btm_ble_start_inquiry(uint8_t mode, uint8_t duration) {
   }
 
   if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
-    btsnd_hcic_ble_set_scan_params(
+    btm_send_hci_set_scan_params(
         BTM_BLE_SCAN_MODE_ACTI, BTM_BLE_LOW_LATENCY_SCAN_INT,
         BTM_BLE_LOW_LATENCY_SCAN_WIN,
         btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, SP_ADV_ALL);
@@ -1442,14 +1468,12 @@ tBTM_STATUS btm_ble_start_inquiry(uint8_t mode, uint8_t duration) {
              (p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) {
     BTM_TRACE_DEBUG("%s, restart LE scan with low latency scan params",
                     __func__);
-    btsnd_hcic_ble_set_scan_enable(BTM_BLE_SCAN_DISABLE,
-                                   BTM_BLE_DUPLICATE_ENABLE);
-    btsnd_hcic_ble_set_scan_params(
+    btm_send_hci_scan_enable(BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
+    btm_send_hci_set_scan_params(
         BTM_BLE_SCAN_MODE_ACTI, BTM_BLE_LOW_LATENCY_SCAN_INT,
         BTM_BLE_LOW_LATENCY_SCAN_WIN,
         btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, SP_ADV_ALL);
-    btsnd_hcic_ble_set_scan_enable(BTM_BLE_SCAN_ENABLE,
-                                   BTM_BLE_DUPLICATE_DISABLE);
+    btm_send_hci_scan_enable(BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE);
   }
 
   if (status == BTM_CMD_STARTED) {
@@ -2144,10 +2168,8 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, uint8_t addr_type,
  ******************************************************************************/
 tBTM_STATUS btm_ble_start_scan(void) {
   tBTM_BLE_INQ_CB* p_inq = &btm_cb.ble_ctr_cb.inq_var;
-
   /* start scan, disable duplicate filtering */
-  btsnd_hcic_ble_set_scan_enable(BTM_BLE_SCAN_ENABLE,
-                                 p_inq->scan_duplicate_filter);
+  btm_send_hci_scan_enable(BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter);
 
   if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI)
     btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
@@ -2173,8 +2195,7 @@ void btm_ble_stop_scan(void) {
   btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
 
   /* stop discovery now */
-  btsnd_hcic_ble_set_scan_enable(BTM_BLE_SCAN_DISABLE,
-                                 BTM_BLE_DUPLICATE_ENABLE);
+  btm_send_hci_scan_enable(BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
 
   btm_update_scanner_filter_policy(SP_ADV_ALL);
 }
index f3caadd..e8bc383 100644 (file)
@@ -45,6 +45,11 @@ extern bool btm_ble_cancel_remote_name(BD_ADDR remote_bda);
 
 extern tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode);
 extern tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode);
+extern void btm_send_hci_scan_enable(uint8_t enable, uint8_t filter_duplicates);
+extern void btm_send_hci_set_scan_params(uint8_t scan_type, uint16_t scan_int,
+                                         uint16_t scan_win,
+                                         uint8_t addr_type_own,
+                                         uint8_t scan_filter_policy);
 extern tBTM_STATUS btm_ble_start_inquiry(uint8_t mode, uint8_t duration);
 extern void btm_ble_stop_scan(void);
 extern void btm_clear_all_pending_le_entry(void);
index ff59c86..840c3cc 100644 (file)
@@ -760,8 +760,7 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_PARMS* p_inqparms,
       p_inq->scan_type = INQ_GENERAL;
       p_inq->inq_active = BTM_INQUIRY_INACTIVE;
       btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
-      btsnd_hcic_ble_set_scan_enable(BTM_BLE_SCAN_DISABLE,
-                                     BTM_BLE_DUPLICATE_ENABLE);
+      btm_send_hci_scan_enable(BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
     } else {
       return (BTM_BUSY);
       BTM_TRACE_API("BTM_StartInquiry: return BUSY");
index 4077527..b2f2e82 100644 (file)
@@ -689,3 +689,52 @@ void btsnd_hcic_ble_set_data_length(uint16_t conn_handle, uint16_t tx_octets,
 
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
+
+void btsnd_hcic_ble_set_extended_scan_params(uint8_t own_address_type,
+                                             uint8_t scanning_filter_policy,
+                                             uint8_t scanning_phys,
+                                             scanning_phy_cfg* phy_cfg) {
+  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
+  uint8_t* pp = (uint8_t*)(p + 1);
+
+  uint16_t param_len = 3 + (5 * scanning_phys);
+  p->len = HCIC_PREAMBLE_SIZE + 3 + (5 * param_len);
+  p->offset = 0;
+
+  UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_PARAMETERS);
+  UINT8_TO_STREAM(pp, param_len);
+
+  UINT8_TO_STREAM(pp, own_address_type);
+  UINT8_TO_STREAM(pp, scanning_filter_policy);
+  UINT8_TO_STREAM(pp, scanning_phys);
+
+  for (int i = 0; i < scanning_phys; i++) {
+    UINT8_TO_STREAM(pp, phy_cfg[i].scan_type);
+    UINT16_TO_STREAM(pp, phy_cfg[i].scan_int);
+    UINT16_TO_STREAM(pp, phy_cfg[i].scan_win);
+  }
+
+  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+void btsnd_hcic_ble_set_extended_scan_enable(uint8_t enable,
+                                             uint8_t filter_duplicates,
+                                             uint16_t duration,
+                                             uint16_t period) {
+  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
+  uint8_t* pp = (uint8_t*)(p + 1);
+
+  const int param_len = 6;
+  p->len = HCIC_PREAMBLE_SIZE + param_len;
+  p->offset = 0;
+
+  UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_ENABLE);
+  UINT8_TO_STREAM(pp, param_len);
+
+  UINT8_TO_STREAM(pp, enable);
+  UINT8_TO_STREAM(pp, filter_duplicates);
+  UINT16_TO_STREAM(pp, duration);
+  UINT16_TO_STREAM(pp, period);
+
+  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
index e98c12c..f915ec6 100644 (file)
 #define HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH (0x003A | HCI_GRP_BLE_CMDS)
 #define HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS \
   (0x003B | HCI_GRP_BLE_CMDS)
+#define HCI_LE_SET_EXTENDED_SCAN_PARAMETERS (0x0041 | HCI_GRP_BLE_CMDS)
+#define HCI_LE_SET_EXTENDED_SCAN_ENABLE (0x0042 | HCI_GRP_BLE_CMDS)
 
 /* LE Get Vendor Capabilities Command OCF */
 #define HCI_BLE_VENDOR_CAP_OCF (0x0153 | HCI_GRP_VENDOR_SPECIFIC)
index 2c7e4a3..766c978 100644 (file)
@@ -798,6 +798,25 @@ extern void btsnd_hcic_ble_add_device_resolving_list(
     uint8_t addr_type_peer, BD_ADDR bda_peer,
     uint8_t irk_peer[HCIC_BLE_IRK_SIZE], uint8_t irk_local[HCIC_BLE_IRK_SIZE]);
 
+struct scanning_phy_cfg {
+  uint8_t scan_type;
+  uint16_t scan_int;
+  uint16_t scan_win;
+};
+
+extern void btsnd_hcic_ble_set_extended_scan_params(
+    uint8_t own_address_type, uint8_t scanning_filter_policy,
+    uint8_t scanning_phys, scanning_phy_cfg* phy_cfg);
+
+extern void btsnd_hcic_ble_set_extended_scan_enable(uint8_t enable,
+                                                    uint8_t filter_duplicates,
+                                                    uint16_t duration,
+                                                    uint16_t period);
+
+extern void btsnd_hcic_ble_add_device_resolving_list(
+    uint8_t addr_type_peer, BD_ADDR bda_peer,
+    uint8_t irk_peer[HCIC_BLE_IRK_SIZE], uint8_t irk_local[HCIC_BLE_IRK_SIZE]);
+
 extern void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer,
                                                     BD_ADDR bda_peer);