HID: Enhance blacklist logic for restricting SDP.

This patch enhances existing blacklist logic for restricting SDP
for hid devices, by adding BD address and name support in addition
to manufacturer id. Also blacklist logic is added for HID devices not
supporting authentication.
    - Targus mouse does not support authentication, so blacklist logic
      added to disable authentication for such hid devices.
    - Many hid mouse gives out of resource error for incoming connections
      when more than 1 sdp connection is made to them. Current implementaion
      in BD stack performs SDP from 2 layers HID BTA layer to determine hid
      desritors for hid device and btif layer for determining uuid's supported.
      Blacklist logic is enhanced for such devices to not perform sdp from btif
      layer after authentication and directly inform upper layers that sdp is
      complete by adding support for BD address and name based addition to
      blacklist.

Change-Id: I4fe1e016549bb55ad176cd014bf1d5da85b38353
CRs-Fixed: 465421, 568114
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index 7b730bf..e5e030b 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -166,23 +166,13 @@
     uint64_t energy_used;
 } btif_activity_energy_info_cb_t;
 
-typedef struct
-{
-    unsigned int   manufact_id;
-}skip_sdp_entry_t;
-
 #define BTA_SERVICE_ID_TO_SERVICE_MASK(id)       (1 << (id))
 
-#define MAX_SDP_BL_ENTRIES 3
 #define UUID_HUMAN_INTERFACE_DEVICE "00001124-0000-1000-8000-00805f9b34fb"
 
-static skip_sdp_entry_t sdp_blacklist[] = {{76}}; //Apple Mouse and Keyboard
-
 /* This flag will be true if HCI_Inquiry is in progress */
 static BOOLEAN btif_dm_inquiry_in_progress = FALSE;
 
-
-
 /************************************************************************************
 **  Static variables
 ************************************************************************************/
@@ -444,34 +434,95 @@
 
 /*****************************************************************************
 **
+** Function        check_if_auth_bl
+**
+** Description     Checks if a given device is blacklisted to skip authentication
+**
+** Parameters     remote_bdaddr
+**
+** Returns         TRUE if the device is present in blacklist, else FALSE
+**
+*******************************************************************************/
+static bool check_if_auth_bl(bt_bdaddr_t * remote_bdaddr)
+{
+    if (remote_bdaddr == NULL) {
+        LOG_WARN("%s: remote_bdaddr = NULL, returning false", __func__);
+        return FALSE;
+    }
+
+    bt_property_t prop_name;
+    bt_bdname_t bdname;
+
+    if (interop_addr_match(INTEROP_DISABLE_AUTH_FOR_HID_POINTING, remote_bdaddr))
+        return TRUE;
+
+    BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
+                               sizeof(bt_bdname_t), &bdname);
+    if (btif_storage_get_remote_device_property((bt_bdaddr_t *)remote_bdaddr,
+                                              &prop_name) != BT_STATUS_SUCCESS)
+    {
+        LOG_WARN("%s: BT_PROPERTY_BDNAME failed, returning false", __func__);
+        return FALSE;
+    }
+
+    if (bdname.name != NULL &&
+        interop_name_match(INTEROP_DISABLE_SDP_AFTER_PAIRING, (const char *)bdname.name))
+        return TRUE;
+
+    char bdstr[20] = {0};
+    LOG_DEBUG("%s: %s is not in blacklist for skipping auth", __func__,
+        bdaddr_to_string(remote_bdaddr, bdstr, sizeof(bdstr)));
+    return FALSE;
+}
+
+/*****************************************************************************
+**
 ** Function        check_sdp_bl
 **
 ** Description     Checks if a given device is blacklisted to skip sdp
 **
-** Parameters     skip_sdp_entry
+** Parameters     remote_bdaddr
 **
 ** Returns         TRUE if the device is present in blacklist, else FALSE
 **
 *******************************************************************************/
 BOOLEAN check_sdp_bl(const bt_bdaddr_t *remote_bdaddr)
 {
+    if (remote_bdaddr == NULL) {
+        LOG_WARN("%s: remote_bdaddr = NULL, returning false", __func__);
+        return FALSE;
+    }
+
+    if (interop_addr_match(INTEROP_DISABLE_SDP_AFTER_PAIRING, remote_bdaddr)) {
+        LOG_WARN("%s: device is in blacklist for skipping sdp", __func__);
+        return TRUE;
+    }
+
+    bt_property_t prop_name;
+    bt_bdname_t bdname;
+    BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
+                               sizeof(bt_bdname_t), &bdname);
+    if (btif_storage_get_remote_device_property((bt_bdaddr_t *)remote_bdaddr,
+                                              &prop_name) != BT_STATUS_SUCCESS)
+    {
+        LOG_WARN("%s: BT_PROPERTY_BDNAME failed, returning false", __func__);
+        return FALSE;
+    }
+
+    if (bdname.name != NULL &&
+        interop_name_match(INTEROP_DISABLE_SDP_AFTER_PAIRING, (const char *)bdname.name))
+        return TRUE;
+
     UINT16 manufacturer = 0;
     UINT8 lmp_ver = 0;
     UINT16 lmp_subver = 0;
-    bt_property_t prop_name;
     bt_remote_version_t info;
 
-
-    if (remote_bdaddr == NULL)
-        return FALSE;
-
-/* fetch additional info about remote device used in iop query */
+    /* fetch additional info about remote device used in iop query */
     BTM_ReadRemoteVersion(*(BD_ADDR*)remote_bdaddr, &lmp_ver,
                     &manufacturer, &lmp_subver);
 
-
-
- /* if not available yet, try fetching from config database */
+    /* if not available yet, try fetching from config database */
     BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_REMOTE_VERSION_INFO,
                             sizeof(bt_remote_version_t), &info);
 
@@ -479,19 +530,21 @@
                                               &prop_name) != BT_STATUS_SUCCESS)
     {
 
+        APPL_TRACE_WARNING("%s: BT_PROPERTY_REMOTE_VERSION_INFO failed, returning false", __func__);
         return FALSE;
     }
     manufacturer = info.manufacturer;
 
-    for (int i = 0; i < MAX_SDP_BL_ENTRIES; i++)
-    {
-        if (manufacturer == sdp_blacklist[i].manufact_id)
-            return TRUE;
-    }
+    if (manufacturer != 0 &&
+        interop_manufacturer_match(INTEROP_DISABLE_SDP_AFTER_PAIRING, manufacturer))
+        return TRUE;
+
+    char bdstr[20] = {0};
+    LOG_DEBUG("%s: %s is not in blacklist for skipping sdp", __func__,
+        bdaddr_to_string(remote_bdaddr, bdstr, sizeof(bdstr)));
     return FALSE;
 }
 
-
 static void bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr, bt_bond_state_t state)
 {
     // Send bonding state only once - based on outgoing/incoming we may receive duplicates
@@ -1109,22 +1162,14 @@
         btif_update_remote_properties(p_auth_cmpl->bd_addr,
                                       p_auth_cmpl->bd_name, NULL, p_auth_cmpl->dev_type);
         pairing_cb.timeout_retries = 0;
-        status = BT_STATUS_SUCCESS;
-        state = BT_BOND_STATE_BONDED;
-        bdcpy(bd_addr.address, p_auth_cmpl->bd_addr);
 
         if (check_sdp_bl(&bd_addr) && check_cod_hid(&bd_addr, COD_HID_MAJOR))
         {
-            LOG_WARN("%s:skip SDP", __FUNCTION__);
-            skip_sdp = TRUE;
-        }
-        if(!pairing_cb.is_local_initiated && skip_sdp)
-        {
-            bond_state_changed(status, &bd_addr, state);
+            bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDED);
 
-            LOG_WARN("%s: Incoming HID Connection",__FUNCTION__);
+            BTIF_TRACE_DEBUG("%s: HID Connection from "
+                "blacklisted device, skipping sdp",__FUNCTION__);
             bt_property_t prop;
-            bt_bdaddr_t bd_addr;
             bt_uuid_t  uuid;
             char uuid_str[128] = UUID_HUMAN_INTERFACE_DEVICE;
 
@@ -1134,12 +1179,18 @@
             prop.val = uuid.uu;
             prop.len = MAX_UUID_SIZE;
 
+            /* Also write this to the NVRAM */
+            status = btif_storage_set_remote_device_property(&bd_addr, &prop);
+            ASSERTC(status == BT_STATUS_SUCCESS, "storing remote services failed", status);
             /* Send the event to the BTIF */
             HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
                              BT_STATUS_SUCCESS, &bd_addr, 1, &prop);
         }
         else
         {
+            status = BT_STATUS_SUCCESS;
+            state = BT_BOND_STATE_BONDED;
+
             /* Trigger SDP on the device */
             pairing_cb.sdp_attempts = 1;;
 
@@ -1167,7 +1218,7 @@
         switch(p_auth_cmpl->fail_reason)
         {
             case HCI_ERR_PAGE_TIMEOUT:
-                if (interop_match(INTEROP_AUTO_RETRY_PAIRING, &bd_addr)
+                if (interop_addr_match(INTEROP_AUTO_RETRY_PAIRING, &bd_addr)
                     && pairing_cb.timeout_retries)
                 {
                     BTIF_TRACE_WARNING("%s() - Pairing timeout; retrying (%d) ...", __FUNCTION__, pairing_cb.timeout_retries);
@@ -2401,6 +2452,48 @@
 
 /*******************************************************************************
 **
+** Function         btif_dm_hh_open_success
+**
+** Description      Checks if device is blacklisted, if yes takes appropriate action
+**
+** Returns          none
+**
+*******************************************************************************/
+
+void btif_dm_hh_open_success(bt_bdaddr_t *bdaddr)
+{
+    if (pairing_cb.state == BT_BOND_STATE_BONDING &&
+            bdcmp(bdaddr->address, pairing_cb.bd_addr) == 0)
+    {
+        if (check_if_auth_bl(bdaddr)
+            && check_cod_hid(bdaddr, COD_HID_MAJOR))
+        {
+            bt_status_t status;
+            LINK_KEY link_key = {0};
+            bond_state_changed(BT_STATUS_SUCCESS, bdaddr, BT_BOND_STATE_BONDED);
+            BTIF_TRACE_DEBUG("%s: Device is blacklisted for authentication", __func__);
+            bt_property_t prop;
+            bt_uuid_t  uuid;
+            char uuid_str[128] = UUID_HUMAN_INTERFACE_DEVICE;
+            string_to_uuid(uuid_str, &uuid);
+            prop.type = BT_PROPERTY_UUIDS;
+            prop.val = uuid.uu;
+            prop.len = MAX_UUID_SIZE;
+            // Also write this to the NVRAM
+            status = btif_storage_set_remote_device_property(bdaddr, &prop);
+            ASSERTC(status == BT_STATUS_SUCCESS, "storing remote services failed", status);
+            // Store fake link for device as bonded in nvram,
+            // otherwise on device reboot/bt off-on device will not be shown in paired list.
+            btif_storage_add_bonded_device(bdaddr, link_key, HCI_LKEY_TYPE_UNAUTH_COMB, 0);
+            // Send the event to the BTIF
+            HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+                             BT_STATUS_SUCCESS, bdaddr, 1, &prop);
+        }
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         btif_dm_hh_open_failed
 **
 ** Description      informs the upper layers if the HH have failed during bonding