Support for reading LE specific controller features

Support for reading LE specific controller features via get adapter properties
API

Change-Id: Ia0b813be45fb826ce27d1d7a31ca41650d7286dd
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index ed79803..cf05a80 100644
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -112,6 +112,7 @@
     #endif
 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
 static void bta_dm_observe_cmpl_cb (void * p_result);
+static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
 
 #ifndef BTA_DM_BLE_ADV_CHNL_MAP
 #define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39)
@@ -3167,6 +3168,10 @@
 
     if(bta_dm_cb.p_sec_cback)
         bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
+
+#if ( BLE_INCLUDED == TRUE)
+    BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback);
+#endif
 }
 
 /*******************************************************************************
@@ -5697,4 +5702,30 @@
     bta_sys_vs_hdl(BTA_VS_BLE_SCAN_PF_COND_EVT, (void *)&param);
 }
 #endif  /* BLE_ANDROID_CONTROLLER_SCAN_FILTER */
+
+/*******************************************************************************
+**
+** Function         bta_dm_ctrl_features_rd_cmpl_cback
+**
+** Description      callback to handle controller feature read complete
+**
+** Parameters:
+**
+*******************************************************************************/
+static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
+{
+    APPL_TRACE_DEBUG2("%s  status = %d ", __FUNCTION__, result);
+    if (result == BTM_SUCCESS)
+    {
+        if(bta_dm_cb.p_sec_cback)
+            bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
+    }
+    else
+    {
+        APPL_TRACE_ERROR2("%s Ctrl BLE feature read failed: status :%d",__FUNCTION__, result);
+    }
+
+}
+
+
 #endif  /* BLE_INCLUDED */
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index 4bb305d..0b7d960 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -591,6 +591,7 @@
 // btla-specific --
 #define BTA_DM_DEV_UNPAIRED_EVT         23
 #define BTA_DM_HW_ERROR_EVT             24      /* BT Chip H/W error */
+#define BTA_DM_LE_FEATURES_READ         25      /* Cotroller specific LE features are read */
 typedef UINT8 tBTA_DM_SEC_EVT;
 
 /* Structure associated with BTA_DM_ENABLE_EVT */
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 77381ef..8126b6b 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -608,7 +608,7 @@
     /* callback to HAL */
     if (status == BTA_SUCCESS)
     {
-#if (BLE_INCLUDED == TRUE && BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE)
+#if (BLE_INCLUDED == TRUE )
         BTA_BrcmInit();
 #endif
         /* initialize a2dp service */
@@ -1026,7 +1026,30 @@
             prop.type = p_req->read_req.type;
             prop.val = (void*)buf;
             prop.len = sizeof(buf);
-            status = btif_storage_get_adapter_property(&prop);
+            if (prop.type == BT_PROPERTY_LOCAL_LE_FEATURES)
+            {
+                tBTM_BLE_VSC_CB cmn_vsc_cb;
+                bt_local_le_features_t local_le_features;
+
+                /* LE features are not stored in storage. Should be retrived from stack */
+                BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
+                local_le_features.local_privacy_enabled = BTM_BleLocalPrivacyEnabled();
+
+                prop.len = sizeof (bt_local_le_features_t);
+                if (cmn_vsc_cb.filter_support == 1)
+                    local_le_features.max_adv_filter_supported = cmn_vsc_cb.max_filter;
+                else
+                    local_le_features.max_adv_filter_supported = 0;
+                local_le_features.max_adv_instance = cmn_vsc_cb.adv_inst_max;
+                local_le_features.max_irk_list_size = cmn_vsc_cb.max_irk_list_sz;
+                local_le_features.rpa_offload_supported = cmn_vsc_cb.rpa_offloading;
+                local_le_features.scan_result_storage_size = cmn_vsc_cb.tot_scan_results_strg;
+                memcpy(prop.val, &local_le_features, prop.len);
+            }
+            else
+            {
+                status = btif_storage_get_adapter_property(&prop);
+            }
             HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, &prop);
         } break;
 
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index 662883a..874aaeb 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -1356,6 +1356,7 @@
 
              #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
              /* Enable local privacy */
+             /*TODO  Should this call be exposed to JAVA...? */
              BTA_DmBleConfigLocalPrivacy(TRUE);
              #endif
         }
@@ -1607,6 +1608,34 @@
             BTIF_TRACE_DEBUG0("BTA_DM_BLE_KEY_EVT. ");
             btif_dm_ble_auth_cmpl_evt(&p_data->auth_cmpl);
             break;
+
+        case BTA_DM_LE_FEATURES_READ:
+        {
+            tBTM_BLE_VSC_CB cmn_vsc_cb;
+            bt_local_le_features_t local_le_features;
+            char buf[512];
+            bt_property_t prop;
+            prop.type = BT_PROPERTY_LOCAL_LE_FEATURES;
+            prop.val = (void*)buf;
+            prop.len = sizeof(buf);
+
+           /* LE features are not stored in storage. Should be retrived from stack */
+            BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
+            local_le_features.local_privacy_enabled = BTM_BleLocalPrivacyEnabled();
+
+            prop.len = sizeof (bt_local_le_features_t);
+            if (cmn_vsc_cb.filter_support == 1)
+                local_le_features.max_adv_filter_supported = cmn_vsc_cb.max_filter;
+             else
+                local_le_features.max_adv_filter_supported = 0;
+            local_le_features.max_adv_instance = cmn_vsc_cb.adv_inst_max;
+            local_le_features.max_irk_list_size = cmn_vsc_cb.max_irk_list_sz;
+            local_le_features.rpa_offload_supported = cmn_vsc_cb.rpa_offloading;
+            local_le_features.scan_result_storage_size = cmn_vsc_cb.tot_scan_results_strg;
+            memcpy(prop.val, &local_le_features, prop.len);
+            HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop);
+            break;
+         }
 #endif
 
         case BTA_DM_AUTHORIZE_EVT:
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index f971bfb..9d6eb2a 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -52,6 +52,8 @@
 #define MIN_ADV_LENGTH                       2
 
 extern tBTM_BLE_MULTI_ADV_CB  btm_multi_adv_cb;
+static tBTM_BLE_CTRL_FEATURES_CBACK    *p_ctrl_le_feature_rd_cmpl_cback = NULL;
+
 
 /*******************************************************************************
 **  Local functions
@@ -431,12 +433,14 @@
 *******************************************************************************/
 static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_params)
 {
-    BTM_TRACE_EVENT ("btm_ble_vendor_capability_vsc_cmpl_cback");
     UINT8  status = 0xFF, *p;
     UINT8  rpa_offloading, max_irk_list_sz, filtering_support, max_filter;
     UINT16 scan_result_storage;
     tBTM_BLE_VENDOR_CB  *p_vcb = &btm_ble_vendor_cb;
     max_irk_list_sz = 0;
+
+    BTM_TRACE_DEBUG("btm_ble_vendor_capability_vsc_cmpl_cback");
+
     /* Check status of command complete event */
     if((p_vcs_cplt_params->opcode == HCI_BLE_VENDOR_CAP_OCF)
         &&(p_vcs_cplt_params->param_len > 0 ))
@@ -447,30 +451,61 @@
 
     if(status == HCI_SUCCESS)
     {
-        STREAM_TO_UINT8  (btm_multi_adv_cb.adv_inst_max, p);
-        STREAM_TO_UINT8  (rpa_offloading, p);
-        STREAM_TO_UINT16 (scan_result_storage, p);
-        STREAM_TO_UINT8  (max_irk_list_sz, p);
-        STREAM_TO_UINT8  (filtering_support, p);
-        STREAM_TO_UINT8  (max_filter, p);
+        STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.adv_inst_max, p);
+        STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.rpa_offloading, p);
+        STREAM_TO_UINT16 (btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg, p);
+        STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, p);
+        STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.filter_support, p);
+        STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.max_filter, p);
     }
     p_vcb->irk_avail_size = max_irk_list_sz;
-    BTM_TRACE_EVENT ("btm_ble_vendor_capability_vsc_cmpl_cback:%d, status=%d, max_irk_size=%d", btm_multi_adv_cb.adv_inst_max, status,btm_ble_vendor_cb.irk_avail_size);
+
+    if (p_ctrl_le_feature_rd_cmpl_cback != NULL)
+        p_ctrl_le_feature_rd_cmpl_cback(status);
+
+    BTM_TRACE_DEBUG("btm_ble_vendor_capability_vsc_cmpl_cback:%d, status=%d, max_irk_size=%d",
+        btm_multi_adv_cb.adv_inst_max, status,btm_ble_vendor_cb.irk_avail_size);
 }
 
 /*******************************************************************************
 **
-** Function         btm_ble_vendor_capability_init
+** Function         BTM_BleGetVendorCapabilities
 **
-** Description      LE Get_Vendor Capabilities
+** Description      This function reads local LE features
 **
-** Returns          None.
+** Parameters       p_cmn_vsc_cb : Locala LE capability structure
+**
+** Returns          void
 **
 *******************************************************************************/
-void btm_ble_vendor_capability_init(void)
+BTM_API extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb)
 {
-    BTM_TRACE_ERROR("btm_ble_vendor_capability_init");
+    BTM_TRACE_DEBUG("btm_ble_vendor_capability_init");
+
+    if(NULL != p_cmn_vsc_cb)
+    {
+        *p_cmn_vsc_cb = btm_cb.cmn_ble_vsc_cb;
+    }
+}
+
+/******************************************************************************
+**
+** Function         BTM_BleReadControllerFeatures
+**
+** Description      Reads BLE specific controller features
+**
+** Parameters:      tBTM_BLE_CTRL_FEATURES_CBACK : Callback to notify when features are read
+**
+** Returns          void
+**
+*******************************************************************************/
+BTM_API extern void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK  *p_vsc_cback)
+{
+    BTM_TRACE_DEBUG("BTM_BleReadControllerFeatures");
+
     memset(&btm_ble_vendor_cb, 0, sizeof(tBTM_BLE_VENDOR_CB));
+
+    p_ctrl_le_feature_rd_cmpl_cback = p_vsc_cback;
     if ( BTM_VendorSpecificCommand (HCI_BLE_VENDOR_CAP_OCF,
                                     0,
                                     NULL,
@@ -547,6 +582,20 @@
 
 /*******************************************************************************
 **
+** Function         BTM_BleLocalPrivacyEnabled
+**
+** Description        Checks if local device supports private address
+**
+** Returns          Return TRUE if local privacy is enabled else FALSE
+**
+*******************************************************************************/
+BOOLEAN BTM_BleLocalPrivacyEnabled()
+{
+    return btm_cb.ble_ctr_cb.privacy;
+}
+
+/*******************************************************************************
+**
 ** Function         btm_ble_resolve_random_addr_on_adv
 **
 ** Description      resolve random address complete callback.
@@ -2984,8 +3033,6 @@
 #if BLE_MULTI_ADV_INCLUDED == TRUE
     btm_ble_multi_adv_init();
 #endif
-
-    btm_ble_vendor_capability_init();
 }
 
 /*******************************************************************************
diff --git a/stack/btm/btm_devctl.c b/stack/btm/btm_devctl.c
index 351db96..c837c16 100644
--- a/stack/btm/btm_devctl.c
+++ b/stack/btm/btm_devctl.c
@@ -672,7 +672,6 @@
      memset(&btm_cb.ble_ctr_cb.bg_dev_list, 0, (sizeof(tBTM_LE_BG_CONN_DEV)*BTM_BLE_MAX_BG_CONN_DEV_NUM));
      gatt_reset_bgdev_list();
      btm_ble_multi_adv_init();
-     btm_ble_vendor_capability_init();
 #endif
     }
 }
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index 2d4e107..d115c3d 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -848,6 +848,7 @@
     BT_OCTET8               enc_rand;   /* received rand value from LTK request*/
     UINT16                  ediv;       /* received ediv value from LTK request */
     UINT8                   key_size;
+    tBTM_BLE_VSC_CB         cmn_ble_vsc_cb;
 #endif
 
                                             /* Packet types supported by the local device */
diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h
index 3e1bf7b..7b06f9a 100644
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -304,6 +304,17 @@
 #define BTM_BLE_ADV_TX_POWER_MAX        4           /* maximum tx power */
 typedef UINT8 tBTM_BLE_ADV_TX_POWER;
 
+
+typedef struct
+{
+    UINT8 adv_inst_max;         /* max adv instance supported in controller */
+    UINT8 rpa_offloading;
+    UINT16 tot_scan_results_strg;
+    UINT8 max_irk_list_sz;
+    UINT8 filter_support;
+    UINT8 max_filter;
+}tBTM_BLE_VSC_CB;
+
 /* slave preferred connection interval range */
 typedef struct
 {
@@ -456,6 +467,7 @@
 typedef UINT8   tBTM_BLE_CONN_TYPE;
 
 typedef BOOLEAN (tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda,     UINT8 *p_remote_name);
+typedef void (tBTM_BLE_CTRL_FEATURES_CBACK)(tBTM_STATUS status);
 
 /* callback function for SMP signing algorithm, signed data in little endian order with tlen bits long */
 typedef void (tBTM_BLE_SIGN_CBACK)(void *p_ref_data, UINT8 *p_signing_data);
@@ -569,7 +581,18 @@
 *******************************************************************************/
 BTM_API extern void BTM_BleSetScanParams(UINT16 scan_interval, UINT16 scan_window,
                                          tBTM_BLE_SCAN_MODE scan_type);
-
+/*******************************************************************************
+**
+** Function         BTM_BleGetVendorCapabilities
+**
+** Description      This function reads local LE features
+**
+** Parameters       p_cmn_vsc_cb : Locala LE capability structure
+**
+** Returns          void
+**
+*******************************************************************************/
+BTM_API extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb);
 /*******************************************************************************
 **
 ** Function         BTM_BleWriteScanRsp
@@ -836,7 +859,19 @@
 **
 *******************************************************************************/
 BTM_API extern  void BTM_BleSetConnScanParams (UINT16 scan_interval, UINT16 scan_window);
-BTM_API extern  void btm_ble_vendor_capability_init(void);
+
+/******************************************************************************
+**
+** Function         BTM_BleReadControllerFeatures
+**
+** Description      Reads BLE specific controller features
+**
+** Parameters:      tBTM_BLE_CTRL_FEATURES_CBACK : Callback to notify when features are read
+**
+** Returns          void
+**
+*******************************************************************************/
+BTM_API extern void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK  *p_vsc_cback);
 
 /*******************************************************************************
 **
@@ -912,6 +947,19 @@
 
 /*******************************************************************************
 **
+** Function         BTM_BleLocalPrivacyEnabled
+**
+** Description        Checks if local device supports private address
+**
+** Returns          Return TRUE if local privacy is enabled else FALSE
+**
+*******************************************************************************/
+BTM_API extern BOOLEAN BTM_BleLocalPrivacyEnabled();
+
+
+
+/*******************************************************************************
+**
 ** Function         BTM_BleSetConnMode
 **
 ** Description      This function is called to set BLE connectable mode for a