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

Commit 208e6238 authored by Ruina Liu's avatar Ruina Liu Committed by Andre Eisenbach
Browse files

Fix Bluetooth crash when pairing with 8th HOGP device

In function bta_hh_hdl_event, when handling with
the event of BTA_HH_API_GET_DSCP_EVT after bonded
with 8th HOGP device, no correct p_cb will be found,
due to mapping error between the device handle and
dev cb for HOGP. Then NPE happen.
Change to map le_cb_index into the device handle for
HOGP, so that HOGP and HID can be separately maintained
maximum to 14 device

Test: Pair with 14 HOGP devices
Change-Id: I8556f1ffea160862c2e52f874ef334f68c17050e
parent 85457765
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -932,6 +932,7 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data) {
#if (BTA_HH_LE_INCLUDED == TRUE)
        if (bta_hh_is_le_device(p_cb, p_data->api_conn.bd_addr)) {
          dev_info.handle = bta_hh_le_add_device(p_cb, p_dev_info);
          if (dev_info.handle != BTA_HH_INVALID_HANDLE)
            dev_info.status = BTA_HH_OK;
        } else
#endif
+1 −1
Original line number Diff line number Diff line
@@ -284,7 +284,7 @@ typedef struct {
  uint8_t cb_index[BTA_HH_MAX_KNOWN];     /* maintain a CB index
                                        map to dev handle */
#if (BTA_HH_LE_INCLUDED == TRUE)
  uint8_t le_cb_index[BTA_HH_MAX_DEVICE]; /* maintain a CB index map to LE dev
  uint8_t le_cb_index[BTA_HH_LE_MAX_KNOWN]; /* maintain a CB index map to LE dev
                                             handle */
  tGATT_IF gatt_if;
#endif
+39 −4
Original line number Diff line number Diff line
@@ -324,7 +324,7 @@ void bta_hh_le_enable(void) {

  bta_hh_cb.gatt_if = BTA_GATTS_INVALID_IF;

  for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++)
  for (xx = 0; xx < ARRAY_SIZE(bta_hh_cb.le_cb_index); xx++)
    bta_hh_cb.le_cb_index[xx] = BTA_HH_IDX_INVALID;

  BTA_GATTC_AppRegister(bta_hh_gattc_callback,
@@ -385,6 +385,28 @@ bool bta_hh_is_le_device(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) {
  return p_cb->is_le_device;
}

/******************************************************************************
 *
 * Function         bta_hh_le_get_le_cb
 *
 * Description      Allocate bta_hh_cb.le_cb_index
 *
 * Parameters:
 *
 ******************************************************************************/
uint8_t bta_hh_le_get_le_dev_hdl(uint8_t cb_index) {
  uint8_t i;
  for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
    if (bta_hh_cb.le_cb_index[i] == cb_index) return BTA_HH_GET_LE_DEV_HDL(i);
  }

  for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
    if (bta_hh_cb.le_cb_index[i] == BTA_HH_IDX_INVALID)
      return BTA_HH_GET_LE_DEV_HDL(i);
  }
  return BTA_HH_IDX_INVALID;
}

/*******************************************************************************
 *
 * Function         bta_hh_le_open_conn
@@ -395,8 +417,15 @@ bool bta_hh_is_le_device(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) {
 *
 ******************************************************************************/
void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) {
  tBTA_HH_STATUS status = BTA_HH_ERR_NO_RES;

  /* update cb_index[] map */
  p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index);
  p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
  if (p_cb->hid_handle == BTA_HH_IDX_INVALID) {
    bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status);
    return;
  }

  p_cb->addr = remote_bda;
  bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
  p_cb->in_use = true;
@@ -1271,10 +1300,15 @@ void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_buf) {
      ((p2[4]) << 8) + p2[5], p_data->status);

  if (p_data->status == GATT_SUCCESS) {
    p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
    if (p_cb->hid_handle == BTA_HH_IDX_INVALID) {
      p_cb->conn_id = p_data->conn_id;
      bta_hh_le_api_disc_act(p_cb);
      return;
    }
    p_cb->is_le_device = true;
    p_cb->in_use = true;
    p_cb->conn_id = p_data->conn_id;
    p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index);

    bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;

@@ -2113,7 +2147,8 @@ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb, bool check_bond) {
 ******************************************************************************/
uint8_t bta_hh_le_add_device(tBTA_HH_DEV_CB* p_cb,
                             tBTA_HH_MAINT_DEV* p_dev_info) {
  p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index);
  p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
  if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) return BTA_HH_INVALID_HANDLE;
  bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;

  /* update DI information */
+6 −1
Original line number Diff line number Diff line
@@ -79,8 +79,13 @@ typedef uint16_t tBTA_HH_EVT;

#if (BTA_HH_LE_INCLUDED == TRUE)
/* GATT_MAX_PHY_CHANNEL can not exceed 14 for the design of BTA HH */
#if GATT_MAX_PHY_CHANNEL > 14
#define BTA_HH_LE_MAX_KNOWN 14
#else
#define BTA_HH_LE_MAX_KNOWN GATT_MAX_PHY_CHANNEL
#define BTA_HH_MAX_DEVICE (HID_HOST_MAX_DEVICES + GATT_MAX_PHY_CHANNEL)
#endif

#define BTA_HH_MAX_DEVICE (HID_HOST_MAX_DEVICES + BTA_HH_LE_MAX_KNOWN)
#else
#define BTA_HH_MAX_DEVICE HID_HOST_MAX_DEVICES
#endif