OSDN Git Service

eSCO: Limit number of retries after mSBC connection failure
authorJack He <siyuanh@google.com>
Wed, 7 Jun 2017 23:44:30 +0000 (16:44 -0700)
committerJack He <siyuanh@google.com>
Fri, 9 Jun 2017 23:18:43 +0000 (23:18 +0000)
* When peer device supports mSBC and codec negotiation, Fluoride stack
  will try to do the following when establishing a eSCO/SCO connection:
    1) Negotiate to mSBC by sending +BCS:2
    2) Try establishing eSCO/SCO connection using mSBC T2 settings
    3) If that failed, downgrade to mSBC T1 settings and retry
    4) If that failed, re-negotiate codec to CVSD, by sending +BCS:1
    5) Retry using CVSD S4 (HFP 1.7 and above) or S3 settings
    6) If this failed stop trying and report failure to upper stack
* Retry is achieved by:
    * Retry is only possible when inuse_codec = BTA_AG_CODEC_MSBC
    * Set codec_msbc_settings to BTA_AG_SCO_MSBC_SETTINGS_T1 when T2
       failed to connect in step 3 above
    * Set codec_fallback to true when T1 failed so that CVSD is used
       in step 4 above
* Retry stop is achieved by:
    * Set inuse_codec = BTA_AG_CODEC_CVSD
    * Set codec_msbc_settings back to BTA_AG_SCO_MSBC_SETTINGS_T2
    * Set codec_fallback to false and codec_updated to true so that
      the stack is ready for the next application triggerred SCO
      connection attempt
* Removed retry_with_sco_only as both Setup Synchronous Connection
  Command (0x0028) and Enhanced Setup Synchronous Connection Command
  (0x003D) fall back to SCO connection if eSCO is not supported.
  See page 858/2772 and 895/2772 of BT4.2 specification document
* Besides both code paths are the same for retry_with_sco_only after
  eSCO changes went in

Bug: 62426841
Test: make, HFP regression, testplans/91406
Change-Id: I205311c55e8763c48b6eb43c27f242927384036e
(cherry picked from commit e82e56bb2a1e5565b73333b60dc6b30936f52e80)

bta/ag/bta_ag_int.h
bta/ag/bta_ag_main.cc
bta/ag/bta_ag_sco.cc
bta/hf_client/bta_hf_client_int.h
bta/hf_client/bta_hf_client_sco.cc

index b180912..c980028 100644 (file)
@@ -251,7 +251,6 @@ typedef struct {
   uint8_t roam_ind;         /* CIEV roam indicator value */
   uint8_t battchg_ind;      /* CIEV battery charge indicator value */
   uint8_t callheld_ind;     /* CIEV call held indicator value */
-  bool retry_with_sco_only; /* indicator to try with SCO only when eSCO fails */
   uint32_t bia_masked_out;  /* indicators HF does not want us to send */
   alarm_t* collision_timer;
   alarm_t* ring_timer;
index 30b59a7..908ccde 100644 (file)
@@ -260,6 +260,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
       p_scb->in_use = true;
       p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
       p_scb->codec_updated = false;
+      p_scb->codec_fallback = false;
       p_scb->peer_codecs = BTA_AG_CODEC_CVSD;
       p_scb->sco_codec = BTA_AG_CODEC_CVSD;
       /* set up timers */
index 6ca7bf0..e67c122 100644 (file)
@@ -175,14 +175,20 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
         bta_ag_cb.sco.p_curr_scb->state = BTA_AG_SCO_CODEC_ST;
         if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings ==
             BTA_AG_SCO_MSBC_SETTINGS_T2) {
-          APPL_TRACE_DEBUG("%s: Fallback to mSBC T1 settings", __func__);
+          APPL_TRACE_WARNING(
+              "%s: eSCO/SCO failed to open, falling back to mSBC T1 settings",
+              __func__);
           bta_ag_cb.sco.p_curr_scb->codec_msbc_settings =
               BTA_AG_SCO_MSBC_SETTINGS_T1;
         } else {
-          APPL_TRACE_DEBUG("%s: Fallback to CVSD", __func__);
+          APPL_TRACE_WARNING(
+              "%s: eSCO/SCO failed to open, falling back to CVSD", __func__);
           bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
         }
       }
+    } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
+      APPL_TRACE_ERROR("%s: eSCO/SCO failed to open, no more fall back",
+                       __func__);
     }
 
     bta_ag_cb.sco.p_curr_scb->inuse_codec = BTA_AG_CODEC_NONE;
@@ -352,6 +358,11 @@ static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, uint8_t event) {
  *
  ******************************************************************************/
 static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
+  APPL_TRACE_DEBUG(
+      "%s: BEFORE codec_updated=%d, codec_fallback=%d, "
+      "sco_codec=%d, peer_codec=%d, msbc_settings=%d",
+      __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec,
+      p_scb->peer_codecs, p_scb->codec_msbc_settings);
   tBTA_AG_PEER_CODEC esco_codec = BTA_AG_CODEC_CVSD;
 
   /* Make sure this SCO handle is not already in use */
@@ -361,18 +372,15 @@ static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
     return;
   }
 
-  APPL_TRACE_DEBUG("%s: Using enhanced SCO setup command %d", __func__,
-                   controller_get_interface()
-                       ->supports_enhanced_setup_synchronous_connection());
-
-  if ((p_scb->sco_codec == BTA_AG_CODEC_MSBC) && !p_scb->codec_fallback &&
-      !p_scb->retry_with_sco_only)
+  if ((p_scb->sco_codec == BTA_AG_CODEC_MSBC) && !p_scb->codec_fallback)
     esco_codec = BTA_AG_CODEC_MSBC;
 
   if (p_scb->codec_fallback) {
     p_scb->codec_fallback = false;
     /* Force AG to send +BCS for the next audio connection. */
     p_scb->codec_updated = true;
+    /* Reset mSBC settings to T2 for the next audio connection */
+    p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
   }
 
   esco_codec_t codec_index = ESCO_CODEC_CVSD;
@@ -404,32 +412,9 @@ static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
   /* If initiating, setup parameters to start SCO/eSCO connection */
   if (is_orig) {
     bta_ag_cb.sco.is_local = true;
-    /* Attempt to use eSCO if remote host supports HFP >= 1.5 */
-    /* HSP does not prohibit eSCO, but no official support, CVSD only */
-    if (p_scb->conn_service == BTA_AG_HFP &&
-        p_scb->peer_version >= HFP_VERSION_1_5 && !p_scb->retry_with_sco_only) {
-      BTM_SetEScoMode(&params);
-      /* If eSCO or EDR eSCO, retry with SCO only in case of failure */
-      if ((params.packet_types & BTM_ESCO_LINK_ONLY_MASK) ||
-          !((params.packet_types &
-             ~(BTM_ESCO_LINK_ONLY_MASK | BTM_SCO_LINK_ONLY_MASK)) ^
-            BTA_AG_NO_EDR_ESCO)) {
-        /* However, do not retry with SCO when using mSBC */
-        if (esco_codec != BTA_AG_CODEC_MSBC) {
-          p_scb->retry_with_sco_only = true;
-        }
-        APPL_TRACE_API("%s: eSCO supported, retry_with_sco_only=%d", __func__,
-                       p_scb->retry_with_sco_only);
-      }
-    } else {
-      APPL_TRACE_API("%s: eSCO not supported, retry_with_sco_only=%d", __func__,
-                     p_scb->retry_with_sco_only);
-      p_scb->retry_with_sco_only = false;
-      BTM_SetEScoMode(&params);
-    }
-
+    /* Set eSCO Mode */
+    BTM_SetEScoMode(&params);
     bta_ag_cb.sco.p_curr_scb = p_scb;
-
     /* save the current codec as sco_codec can be updated while SCO is open. */
     p_scb->inuse_codec = esco_codec;
 
@@ -441,7 +426,6 @@ static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
   } else {
     /* Not initiating, go to listen mode */
     uint8_t* p_bd_addr = NULL;
-    p_scb->retry_with_sco_only = false;
     p_bd_addr = p_scb->peer_addr;
 
     tBTM_STATUS status =
@@ -454,6 +438,11 @@ static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
                    __func__, is_orig, p_scb->sco_idx, status,
                    params.packet_types);
   }
+  APPL_TRACE_DEBUG(
+      "%s: AFTER codec_updated=%d, codec_fallback=%d, "
+      "sco_codec=%d, peer_codec=%d, msbc_settings=%d",
+      __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec,
+      p_scb->peer_codecs, p_scb->codec_msbc_settings);
 }
 
 /*******************************************************************************
@@ -528,25 +517,6 @@ static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {
 
 /*******************************************************************************
  *
- * Function         bta_ag_attempt_msbc_safe_settings
- *
- * Description    Checks if ESCO connection needs to be attempted using mSBC
- *                T1(safe) settings
- *
- *
- * Returns          true if T1 settings has to be used, false otherwise
- *
- ******************************************************************************/
-bool bta_ag_attempt_msbc_safe_settings(tBTA_AG_SCB* p_scb) {
-  if (p_scb->svc_conn && p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
-      p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1)
-    return true;
-  else
-    return false;
-}
-
-/*******************************************************************************
- *
  * Function         bta_ag_codec_negotiation_timer_cback
  *
  * Description
@@ -1289,7 +1259,6 @@ void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb,
   /* call app callback */
   bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
 
-  p_scb->retry_with_sco_only = false;
   /* reset to mSBC T2 settings as the preferred */
   p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
 }
@@ -1311,17 +1280,13 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
   p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
 
   /* codec_fallback is set when AG is initiator and connection failed for mSBC.
-   */
-  /* OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
-  if ((p_scb->codec_fallback && p_scb->svc_conn) ||
-      bta_ag_attempt_msbc_safe_settings(p_scb)) {
+   * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
+  if (p_scb->svc_conn &&
+      (p_scb->codec_fallback ||
+       (p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
+        p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1))) {
     bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
-  } else if (p_scb->retry_with_sco_only && p_scb->svc_conn) {
-    /* retry_with_sco_only is set when AG is initiator and connection failed for
-     * eSCO */
-    bta_ag_create_sco(p_scb, true);
-  }
-  else {
+  } else {
     /* Indicate if the closing of audio is because of transfer */
     bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
 
@@ -1339,7 +1304,6 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
     bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
     p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
   }
-  p_scb->retry_with_sco_only = false;
 }
 
 /*******************************************************************************
index da09b58..6a03d45 100644 (file)
@@ -174,7 +174,6 @@ typedef struct {
   uint16_t sco_idx;                       /* SCO handle */
   uint8_t sco_state;                      /* SCO state variable */
   bool sco_close_rfc; /* true if also close RFCOMM after SCO */
-  bool retry_with_sco_only;
   tBTM_SCO_CODEC_TYPE negotiated_codec; /* negotiated codec */
   bool svc_conn;      /* set to true when service level connection is up */
   bool send_at_reply; /* set to true to notify framework about AT results */
index 2996522..e792c3f 100644 (file)
@@ -236,30 +236,9 @@ static void bta_hf_client_sco_create(tBTA_HF_CLIENT_CB* client_cb,
 
   /* if initiating set current scb and peer bd addr */
   if (is_orig) {
-    /* Attempt to use eSCO if remote host supports HFP >= 1.5 */
-    if (client_cb->peer_version >= HFP_VERSION_1_5 &&
-        !client_cb->retry_with_sco_only) {
-      BTM_SetEScoMode(&params);
-      /* If ESCO or EDR ESCO, retry with SCO only in case of failure */
-      if ((params.packet_types & BTM_ESCO_LINK_ONLY_MASK) ||
-          !((params.packet_types &
-             ~(BTM_ESCO_LINK_ONLY_MASK | BTM_SCO_LINK_ONLY_MASK)) ^
-            BTA_HF_CLIENT_NO_EDR_ESCO)) {
-        client_cb->retry_with_sco_only = true;
-        APPL_TRACE_API("Setting retry_with_sco_only to true");
-      }
-    } else {
-      if (client_cb->retry_with_sco_only)
-        APPL_TRACE_API("retrying with SCO only");
-      client_cb->retry_with_sco_only = false;
-
-      BTM_SetEScoMode(&params);
-    }
-
+    BTM_SetEScoMode(&params);
     /* tell sys to stop av if any */
     bta_sys_sco_use(BTA_ID_HS, 1, client_cb->peer_addr);
-  } else {
-    client_cb->retry_with_sco_only = false;
   }
 
   p_bd_addr = client_cb->peer_addr;
@@ -583,8 +562,6 @@ void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
   } else {
     bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_OPEN_EVT);
   }
-
-  client_cb->retry_with_sco_only = false;
 }
 
 /*******************************************************************************
@@ -611,26 +588,19 @@ void bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA* p_data) {
   /* clear current scb */
   client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
 
-  /* retry_with_sco_only, will be set only when initiator
-  ** and HFClient is first trying to establish an eSCO connection */
-  if (client_cb->retry_with_sco_only && client_cb->svc_conn) {
-    bta_hf_client_sco_create(client_cb, true);
-  } else {
-    bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_CONN_CLOSE_E);
+  bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_CONN_CLOSE_E);
 
-    bta_sys_sco_close(BTA_ID_HS, 1, client_cb->peer_addr);
+  bta_sys_sco_close(BTA_ID_HS, 1, client_cb->peer_addr);
 
-    bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
+  bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
 
-    /* call app callback */
-    bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
+  /* call app callback */
+  bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
 
-    if (client_cb->sco_close_rfc == true) {
-      client_cb->sco_close_rfc = false;
-      bta_hf_client_rfc_do_close(p_data);
-    }
+  if (client_cb->sco_close_rfc == true) {
+    client_cb->sco_close_rfc = false;
+    bta_hf_client_rfc_do_close(p_data);
   }
-  client_cb->retry_with_sco_only = false;
 }
 
 /*******************************************************************************