OSDN Git Service

HID: Set sniff subrate with optimize latency value on HID Link.
authorHemant Gupta <hemantg@codeaurora.org>
Fri, 21 Feb 2014 13:20:41 +0000 (18:50 +0530)
committerLinux Build Service Account <lnxbuild@localhost>
Wed, 24 Aug 2016 14:09:27 +0000 (08:09 -0600)
Current HID design disables sniff on HID Link in presence of SCO/eSCO, which
was leading to many IOT issues, as HID links work in sniff mode, and disabling
sniff on hid leads to issues of connection timeout if anchor points are missed
during sco/esco concurrent usecases. This design is changed as below:

- If HID is connected & SCO is active, then disabling Sniff subrate
  to fix connection timeout on HID link.

- If HID is connected & SCO is not active. Setting sniff subrate with
  optimize value based on the remote parameter to fix connection
  timeout on HID link to avoid HID IOT issues.

- Adds behaviour of host disabling SSR for JW MT002 and prevents
  Host from sending Sniff subrating command to SoC for BORND mouse
  so as to avoid IOT issues of disconnection and slow mouse movements
  respectively with these device.

- Updates SSR parameters for HID Link to have a minimum
  Max latency value for SSR, to have better trade off between power
  consumption as well as performance of HID.

Change-Id: I6d60df88ea33e00b0fb173447351da4874dc97e5
CRs-Fixed: 635632

bta/dm/bta_dm_cfg.c
bta/dm/bta_dm_pm.c
bta/hh/bta_hh_utils.c
bta/include/bta_hh_api.h

index c2b414e..cecc798 100644 (file)
@@ -519,7 +519,7 @@ tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] =
 {
     /*max_lat, min_rmt_to, min_loc_to*/
     {0,      0, 0},     /* BTA_DM_PM_SSR0 - do not use SSR */
-    {0,      0, 2},     /* BTA_DM_PM_SSR1 - HH, can NOT share entry with any other profile,
+    {0,      0, 1600},     /* BTA_DM_PM_SSR1 - HH, can NOT share entry with any other profile,
                            seting default max latency and min remote timeout as 0,
                            and always read individual device preference from HH module */
     {1200,   2, 2},     /* BTA_DM_PM_SSR2 - others (as long as sniff is allowed)*/
index 07de091..ed52577 100644 (file)
@@ -476,7 +476,21 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id,
 #endif
        )
     {
-        bta_dm_pm_ssr(peer_addr);
+        if( ((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
+            ((NULL != (p = BTM_ReadRemoteFeatures (peer_addr))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)))
+        {
+            /* If HID connection open is received and SCO is already active.
+               This will handle the case where HID connects when SCO already active */
+            if ((status == BTA_SYS_CONN_OPEN) && (id == BTA_ID_HH) && bta_dm_pm_is_sco_active())
+            {
+                APPL_TRACE_DEBUG("%s: SCO is Active, disabling SSR on HID link", __func__)
+                BTM_SetSsrParams(peer_addr, 0, 0, 0);
+            }
+            else
+            {
+                bta_dm_pm_ssr(peer_addr);
+            }
+        }
     }
     else
     {
@@ -496,28 +510,18 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id,
             }
         }
     }
-#endif
-
-    bta_dm_pm_set_mode(peer_addr, BTA_DM_PM_NO_ACTION, pm_req);
 
-    /* perform the HID link workaround if needed
-    ** 1. If SCO up/down event is received OR
-    ** 2. If HID connection open is received and SCO is already active.
-    **     This will handle the case where HID connects when SCO already active
-    */
-    if ( BTM_IsDeviceUp() &&
-         ( ((status == BTA_SYS_SCO_OPEN) || (status == BTA_SYS_SCO_CLOSE)) ||
-           ((status == BTA_SYS_CONN_OPEN) && (id == BTA_ID_HH) && bta_dm_pm_is_sco_active()) ) )
+    /* If SCO up/down event is received, then enable/disable SSR on active HID link */
+    if (status == BTA_SYS_SCO_OPEN || status == BTA_SYS_SCO_CLOSE)
     {
-        BOOLEAN bScoActive;
-        if (status == BTA_SYS_CONN_OPEN)
-            bScoActive = TRUE;
-        else
-            bScoActive = (status == BTA_SYS_SCO_OPEN);
+        const bool bScoActive = (status == BTA_SYS_SCO_OPEN);
 
+        APPL_TRACE_DEBUG("%s: bta_dm_pm_hid_check with bScoActive = %d", __func__, bScoActive);
         bta_dm_pm_hid_check(bScoActive);
     }
+#endif
 
+    bta_dm_pm_set_mode(peer_addr, BTA_DM_PM_NO_ACTION, pm_req);
 }
 
 
@@ -866,6 +870,28 @@ static void bta_dm_pm_ssr(BD_ADDR peer_addr)
             {
                 if (bta_hh_read_ssr_param(peer_addr, &p_spec_cur->max_lat, &p_spec_cur->min_rmt_to) == BTA_HH_ERR)
                     continue;
+                if (p_spec_cur->max_lat == BTA_HH_SSR_MAX_LATENCY_ZERO)
+                {
+                    APPL_TRACE_WARNING("%s: Max latency is 0, not sending"
+                        "SSR command as device is blacklisted", __func__);
+                    return;
+                }
+                else if (p_spec_cur->max_lat == BTA_HH_SSR_DISABLE_SSR)
+                {
+                    APPL_TRACE_WARNING("%s: Need to disable SSR"
+                        "as device is blacklisted", __func__);
+                    BTM_SetSsrParams (peer_addr, 0, 0, 0);
+                    return;
+                }
+                else if (p_spec_cur->max_lat > BTA_HH_SSR_MAX_LATENCY_OPTIMAL)
+                {
+                    p_spec_cur->max_lat = BTA_HH_SSR_MAX_LATENCY_OPTIMAL;
+                }
+                else if (p_spec_cur->max_lat < BTA_HH_SSR_MAX_LATENCY_MIN_OPTIMAL)
+                {
+                    p_spec_cur->max_lat = BTA_HH_SSR_MAX_LATENCY_MIN_OPTIMAL;
+                }
+                APPL_TRACE_DEBUG("%s: New Max Latency = %d", __func__, p_spec_cur->max_lat);
             }
 #endif
             if (p_spec_cur->max_lat < p_spec->max_lat ||
@@ -1201,29 +1227,38 @@ static int bta_dm_get_sco_index()
 **
 ** Function         bta_dm_pm_hid_check
 **
-** Description      Disables/Enables sniff in link policy based on SCO Up/Down
+** Description      Disables/Enables SSR based on SCO Up/Down
 **
 ** Returns          None
 **
 *******************************************************************************/
 static void bta_dm_pm_hid_check(BOOLEAN bScoActive)
 {
-    int j;
+    BD_ADDR peer_bdaddr;
 
-    /* if HID is active, disable the link policy */
-    for(j=0; j<bta_dm_conn_srvcs.count ; j++)
+    for(int j=0; j<bta_dm_conn_srvcs.count ; j++)
     {
         /* check if an entry already present */
         if(bta_dm_conn_srvcs.conn_srvc[j].id == BTA_ID_HH )
         {
-            APPL_TRACE_DEBUG ("SCO status change(Active: %d), modify HID link policy. state: %d",
-                bScoActive, bta_dm_conn_srvcs.conn_srvc[j].state);
-            bta_dm_pm_set_sniff_policy( bta_dm_find_peer_device(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr), bScoActive);
-
-            /* if we had disabled link policy, seems like the hid device stop retrying SNIFF after a few tries. force sniff if needed */
-            if (!bScoActive)
-                bta_dm_pm_set_mode(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, BTA_DM_PM_NO_ACTION,
-                                   BTA_DM_PM_RESTART);
+            UINT8 *p = BTM_ReadLocalFeatures();
+            bdcpy(peer_bdaddr, bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr);
+
+            if((p != NULL && HCI_SNIFF_SUB_RATE_SUPPORTED(p))
+                &&((NULL != (p = BTM_ReadRemoteFeatures (peer_bdaddr)))
+                && HCI_SNIFF_SUB_RATE_SUPPORTED(p)))
+            {
+                if (bScoActive)
+                {
+                    APPL_TRACE_DEBUG("%s: SCO_OPEN, disabling SSR", __func__);
+                    BTM_SetSsrParams(peer_bdaddr, 0, 0, 0);
+                }
+                else
+                {
+                    APPL_TRACE_DEBUG("%s: SCO_CLOSE, enabling SSR", __func__);
+                    bta_dm_pm_ssr(peer_bdaddr);
+                }
+            }
         }
     }
 
index c8ea864..8bfed31 100644 (file)
@@ -49,6 +49,46 @@ static const UINT8 bta_hh_mod_key_mask[BTA_HH_MOD_MAX_KEY] =
     BTA_HH_KB_GUI_MASK
 };
 
+/* hid_blacklist_addr_prefix_for_ssr & hid_ssr_max_lat_list_for_iot are used
+   to fix IOP issues of sniff subrate feature */
+static const UINT8 hid_blacklist_addr_prefix_for_ssr[][3] = {
+    {0x00, 0x1B, 0xDC} // ISSC
+    ,{0xdc, 0x2c, 0x26} // BORND
+    ,{0x54, 0x46, 0x6B} // JW MT002
+};
+
+static const UINT16 hid_ssr_max_lat_list_for_iot[] = {
+    0x0012 // ISSC
+    ,BTA_HH_SSR_MAX_LATENCY_ZERO // BORND
+    ,BTA_HH_SSR_DISABLE_SSR // JW MT002
+};
+
+
+/*******************************************************************************
+**      Function       blacklist_adjust_sniff_subrate
+**
+**      Description    It's used to update SSR parameter such as max latency,
+**                     if device is found in HID blacklist.
+**
+**      Returns        None
+*******************************************************************************/
+static void blacklist_adjust_sniff_subrate(BD_ADDR peer_dev, UINT16 *ssr_max_lat)
+{
+    UINT16 old_ssr_max_lat = *ssr_max_lat;
+    const int blacklist_size =
+            sizeof(hid_blacklist_addr_prefix_for_ssr)/sizeof(hid_blacklist_addr_prefix_for_ssr[0]);
+    for (int i = 0; i < blacklist_size; i++) {
+        if (hid_blacklist_addr_prefix_for_ssr[i][0] == peer_dev[0] &&
+            hid_blacklist_addr_prefix_for_ssr[i][1] == peer_dev[1] &&
+            hid_blacklist_addr_prefix_for_ssr[i][2] == peer_dev[2]) {
+            *ssr_max_lat = hid_ssr_max_lat_list_for_iot[i];
+            APPL_TRACE_WARNING("%s: Device in blacklist for ssr, max latency changed "
+                "from %d to %d", __func__, old_ssr_max_lat, *ssr_max_lat);
+            return;
+        }
+    }
+}
+
 
 /*******************************************************************************
 **
@@ -198,6 +238,8 @@ void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
     p_cb->app_id    = app_id;
 
     p_cb->dscp_info.ssr_max_latency = ssr_max_latency;
+    blacklist_adjust_sniff_subrate(p_cb->addr, &(p_cb->dscp_info.ssr_max_latency));
+
     p_cb->dscp_info.ssr_min_tout    = ssr_min_tout;
 
     /* store report descriptor info */
index d43e492..f55664d 100644 (file)
 #define BTA_HH_SSR_MIN_TOUT_DEF     2
 #endif
 
+#ifndef BTA_HH_SSR_MAX_LATENCY_OPTIMAL
+#define BTA_HH_SSR_MAX_LATENCY_OPTIMAL  360 /* 225 ms*/
+#endif
+
+#ifndef BTA_HH_SSR_MAX_LATENCY_MIN_OPTIMAL
+#define BTA_HH_SSR_MAX_LATENCY_MIN_OPTIMAL  256 /* 160 ms*/
+#endif
+
+#ifndef BTA_HH_SSR_MAX_LATENCY_ZERO
+#define BTA_HH_SSR_MAX_LATENCY_ZERO     0
+#endif
+
+#ifndef BTA_HH_SSR_DISABLE_SSR
+#define BTA_HH_SSR_DISABLE_SSR     1
+#endif
+
 /* BTA HID Host callback events */
 #define BTA_HH_ENABLE_EVT       0       /* HH enabled */
 #define BTA_HH_DISABLE_EVT      1       /* HH disabled */