Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f2260a9 authored by Ganesh Ganapathi Batta's avatar Ganesh Ganapathi Batta Committed by Matthew Xie
Browse files

Make host side of Read Local/Remote Extended Features more reliable

Issue Ext feature request only if the local controller supports
the command. Fall back to read remote feature command,
if the extended feature request fails
Bug:8591628

Change-Id: I744d9845c04b30d2dca1fd491fea49616adbb2d7
parent 7d512044
Loading
Loading
Loading
Loading
+33 −11
Original line number Diff line number Diff line
@@ -1406,7 +1406,19 @@ void btm_read_remote_features_complete (UINT8 *p)
    STREAM_TO_ARRAY(p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0], p,
                    HCI_FEATURE_BYTES_PER_PAGE);

    /* Process this features page */
    if ((HCI_LMP_EXTENDED_SUPPORTED(p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) &&
        (HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(btm_cb.devcb.supported_cmds)))
    {
        /* if the remote controller has extended features and local controller supports
        ** HCI_Read_Remote_Extended_Features command then start reading these feature starting
        ** with extended features page 1 */
        BTM_TRACE_DEBUG0 ("Start reading remote extended features");
        btm_read_remote_ext_features(handle, HCI_EXT_FEATURES_PAGE_1);
        return;
    }

    /* Remote controller has no extended features. Process remote controller supported features
       (features page HCI_EXT_FEATURES_PAGE_0). */
    btm_process_remote_ext_features (p_acl_cb, 1);

    /* Continue with HCI connection establishment */
@@ -1433,14 +1445,6 @@ void btm_read_remote_ext_features_complete (UINT8 *p)
    BTM_TRACE_DEBUG0 ("btm_read_remote_ext_features_complete");

    STREAM_TO_UINT8  (status, p);

    if (status != HCI_SUCCESS)
    {
        btm_read_remote_ext_features_failed (status);
        return;
    }

    /* Extract parameters */
    STREAM_TO_UINT16 (handle, p);
    STREAM_TO_UINT8  (page_num, p);
    STREAM_TO_UINT8  (max_page, p);
@@ -1493,9 +1497,27 @@ void btm_read_remote_ext_features_complete (UINT8 *p)
** Returns          void
**
*******************************************************************************/
void btm_read_remote_ext_features_failed (UINT8 status)
void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle)
{
    BTM_TRACE_ERROR1 ("btm_read_remote_ext_features_failed (status 0x%02x)", status);
    tACL_CONN   *p_acl_cb;
    UINT8       acl_idx;

    BTM_TRACE_WARNING2 ("btm_read_remote_ext_features_failed (status 0x%02x) for handle %d",
                         status, handle);

    if ((acl_idx = btm_handle_to_acl_index(handle)) >= MAX_L2CAP_LINKS)
    {
        BTM_TRACE_ERROR1("btm_read_remote_ext_features_failed handle=%d invalid", handle);
        return;
    }

    p_acl_cb = &btm_cb.acl_db[acl_idx];

    /* Process supported features only */
    btm_process_remote_ext_features (p_acl_cb, 1);

    /* Continue HCI connection establishment */
    btm_establish_continue (p_acl_cb);
}

/*******************************************************************************
+115 −42
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ static void btm_read_all_lmp_features_complete (UINT8 max_page_number);
static void btm_set_lmp_features_host_may_support (UINT8 max_page_number);
static void btm_get_local_features (void);
static void btm_issue_host_support_for_lmp_features (void);
static void btm_read_local_supported_cmds (UINT8 local_controller_id);

#if BLE_INCLUDED == TRUE
static void btm_read_ble_local_supported_features (void);
@@ -509,6 +510,24 @@ void btm_get_local_version (void)

}

/*******************************************************************************
**
** Function         btm_read_local_supported_cmds
**
** Description      Local function called to send a read local supported commands
**
** Returns          void
**
*******************************************************************************/
static void btm_read_local_supported_cmds (UINT8 local_controller_id)
{
    BTM_TRACE_DEBUG0("Start reading local supported commands");

    btu_start_timer (&btm_cb.devcb.reset_timer, BTU_TTYPE_BTM_DEV_CTL, BTM_DEV_REPLY_TIMEOUT);

    btsnd_hcic_read_local_supported_cmds(local_controller_id);
}

/*******************************************************************************
**
** Function         btm_get_local_features
@@ -891,8 +910,15 @@ void btm_read_local_version_complete (UINT8 *p, UINT16 evt_len)
        STREAM_TO_UINT16 (p_vi->lmp_subversion, p);
    }

    if (p_vi->hci_version >= HCI_PROTO_VERSION_1_2)
    {
        btm_read_local_supported_cmds(LOCAL_BR_EDR_CONTROLLER_ID);
    }
    else
    {
        btm_get_local_features ();
    }
}

/*******************************************************************************
**
@@ -1214,7 +1240,8 @@ static void btm_issue_host_support_for_lmp_features (void)
        return;
    }

    BTM_TRACE_ERROR1("btm_issue_host_support_for_lmp_features lmp_features_host_may_support: 0x%02x. This is unexpected.", btm_cb.devcb.lmp_features_host_may_support);
    BTM_TRACE_ERROR2("%s lmp_features_host_may_support: 0x%02x. This is unexpected.",__FUNCTION__,
                      btm_cb.devcb.lmp_features_host_may_support);
}

/*******************************************************************************
@@ -1303,10 +1330,9 @@ static void btm_read_all_lmp_features_complete (UINT8 max_page_number)
void btm_read_local_features_complete (UINT8 *p, UINT16 evt_len)
{
    tBTM_DEVCB     *p_devcb = &btm_cb.devcb;
    tBTM_CMPL_CB   *p_cb = p_devcb->p_reset_cmpl_cb;
    UINT8           status;

    btu_stop_timer (&btm_cb.devcb.reset_timer);
    btu_stop_timer (&p_devcb->reset_timer);

    STREAM_TO_UINT8  (status, p);
    if (status == HCI_SUCCESS)
@@ -1315,9 +1341,21 @@ void btm_read_local_features_complete (UINT8 *p, UINT16 evt_len)
        STREAM_TO_ARRAY(p_devcb->local_lmp_features[0],
                p, HCI_FEATURE_BYTES_PER_PAGE);

        if ((HCI_LMP_EXTENDED_SUPPORTED(p_devcb->local_lmp_features[HCI_EXT_FEATURES_PAGE_0])) &&
            (HCI_READ_LOCAL_EXT_FEATURES_SUPPORTED(p_devcb->supported_cmds)))
        {
            /* if local controller has extended features and supports
            **HCI_Read_Local_Extended_Features command,
            ** then start reading these feature starting with extended features page 1 */
            BTM_TRACE_DEBUG0 ("Start reading local extended features");
            btm_get_local_ext_features(HCI_EXT_FEATURES_PAGE_1);
        }
        else
        {
            btm_read_all_lmp_features_complete (HCI_EXT_FEATURES_PAGE_0);
        }
    }
}

/*******************************************************************************
**
@@ -1340,8 +1378,14 @@ void btm_read_local_ext_features_complete (UINT8 *p, UINT16 evt_len)
    btu_stop_timer (&btm_cb.devcb.reset_timer);

    STREAM_TO_UINT8 (status, p);
    if (status == HCI_SUCCESS)

    if (status != HCI_SUCCESS)
    {
        BTM_TRACE_WARNING1("btm_read_local_ext_features_complete status = 0x%02X", status);
        btm_read_all_lmp_features_complete (HCI_EXT_FEATURES_PAGE_0);
        return;
    }

    /* Extract Page number */
    STREAM_TO_UINT8  (page_number, p);

@@ -1360,7 +1404,8 @@ void btm_read_local_ext_features_complete (UINT8 *p, UINT16 evt_len)
            p, HCI_FEATURE_BYTES_PER_PAGE);

    /* If this is re-read of the 1-st extended page after host supported LMP features are set */
        if ((page_number == HCI_EXT_FEATURES_PAGE_1) && (btm_cb.devcb.lmp_features_host_may_support == BTM_RE_READ_1ST_PAGE))
    if ((page_number == HCI_EXT_FEATURES_PAGE_1) &&
        (btm_cb.devcb.lmp_features_host_may_support == BTM_RE_READ_1ST_PAGE))
    {
        btm_cb.devcb.lmp_features_host_may_support &= ~BTM_RE_READ_1ST_PAGE;
        btm_issue_host_support_for_lmp_features();
@@ -1384,6 +1429,34 @@ void btm_read_local_ext_features_complete (UINT8 *p, UINT16 evt_len)
        btm_get_local_ext_features(page_number);
    }
}

/*******************************************************************************
**
** Function         btm_read_local_supported_cmds_complete
**
** Description      This function is called when local supported commands read
**                  is complete.
**
** Returns          void
**
*******************************************************************************/
void btm_read_local_supported_cmds_complete (UINT8 *p)
{
    tBTM_DEVCB     *p_devcb = &btm_cb.devcb;
    UINT8           status;

    btu_stop_timer (&(p_devcb->reset_timer));

    STREAM_TO_UINT8  (status, p);
    BTM_TRACE_DEBUG1("btm_read_local_supported_cmds_complete status (0x%02x)", status);

    if (status == HCI_SUCCESS)
    {
        /* Save the supported commands bit mask */
        STREAM_TO_ARRAY(p_devcb->supported_cmds, p, HCI_NUM_SUPP_COMMANDS_BYTES);
    }

    btm_get_local_features();
}

/*******************************************************************************
+3 −1
Original line number Diff line number Diff line
@@ -220,6 +220,7 @@ typedef struct
#define BTM_HOST_MAY_SUPP_LE            0x04
#define BTM_HOST_MAY_SUPP_SIMULT_BR_LE  0x08
    UINT8               lmp_features_host_may_support;  /* The flags of LMP features host may support via BR/EDR ctrlr + BTM_RE_READ_1ST_PAGE */
    UINT8               supported_cmds[HCI_NUM_SUPP_COMMANDS_BYTES]; /* Supported Commands bit field */

} tBTM_DEVCB;

@@ -967,7 +968,7 @@ BTM_API extern UINT16 btm_get_acl_disc_reason_code (void);
BTM_API extern tBTM_STATUS  btm_remove_acl (BD_ADDR bd_addr);
extern void         btm_read_remote_features_complete (UINT8 *p);
extern void         btm_read_remote_ext_features_complete (UINT8 *p);
extern void         btm_read_remote_ext_features_failed (UINT8 status);
extern void         btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle);
extern void         btm_read_remote_version_complete (UINT8 *p);
// btla-specific ++
extern void         btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type);
@@ -1030,6 +1031,7 @@ extern void btm_dev_timeout (TIMER_LIST_ENT *p_tle);
extern void btm_reset_complete (void);
extern void btm_read_local_version_complete (UINT8 *p, UINT16 evt_len);
extern void btm_read_hci_buf_size_complete (UINT8 *p, UINT16 evt_len);
extern void btm_read_local_supported_cmds_complete (UINT8 *p);
extern void btm_read_local_features_complete (UINT8 *p, UINT16 evt_len);
extern void btm_read_local_ext_features_complete (UINT8 *p, UINT16 evt_len);
extern void btm_read_local_name_complete (UINT8 *p, UINT16 evt_len);
+26 −6
Original line number Diff line number Diff line
@@ -870,11 +870,19 @@ static void btu_hcif_read_rmt_features_comp_evt (UINT8 *p, UINT16 evt_len)
*******************************************************************************/
static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p, UINT16 evt_len)
{
    /* Status is in first byte of stream */
    if (*p == HCI_SUCCESS)
    UINT8 *p_cur = p;
    UINT8 status;
    UINT16 handle;

    STREAM_TO_UINT8 (status, p_cur);

    if (status == HCI_SUCCESS)
        btm_read_remote_ext_features_complete(p);
    else
        btm_read_remote_ext_features_failed(*p);
    {
        STREAM_TO_UINT16 (handle, p_cur);
        btm_read_remote_ext_features_failed(status, handle);
    }
}

/*******************************************************************************
@@ -1036,6 +1044,10 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
            btm_read_hci_buf_size_complete (p, evt_len);
            break;

        case HCI_READ_LOCAL_SUPPORTED_CMDS:
            btm_read_local_supported_cmds_complete (p);
            break;

        case HCI_READ_LOCAL_FEATURES:
            btm_read_local_features_complete (p, evt_len);
            break;
@@ -1341,8 +1353,16 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
                        }
                        break;

                    case HCI_READ_RMT_EXT_FEATURES_COMP_EVT:
                        btm_read_remote_ext_features_failed(status);
                    case HCI_READ_RMT_EXT_FEATURES:
                        if (p_cmd != NULL)
                        {
                            p_cmd++; /* skip command length */
                            STREAM_TO_UINT16 (handle, p_cmd);
                        }
                        else
                            handle = HCI_INVALID_HANDLE;

                        btm_read_remote_ext_features_failed(status, handle);
                        break;

                    case HCI_AUTHENTICATION_REQUESTED:
@@ -1594,7 +1614,7 @@ void btu_hcif_cmd_timeout (UINT8 controller_id)
        case HCI_CREATE_CONNECTION:
        case HCI_CHANGE_CONN_LINK_KEY:
        case HCI_SWITCH_ROLE:
        case HCI_READ_RMT_EXT_FEATURES_COMP_EVT:
        case HCI_READ_RMT_EXT_FEATURES:
        case HCI_AUTHENTICATION_REQUESTED:
        case HCI_SET_CONN_ENCRYPTION:
#if BTM_SCO_INCLUDED == TRUE
+1 −1

File changed.

Contains only whitespace changes.