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

Commit b91aa563 authored by Himanshu Rawat's avatar Himanshu Rawat Committed by Automerger Merge Worker
Browse files

Merge "Prefer to connect HOGP, rather than HID if Hid-over-GATT service is...

Merge "Prefer to connect HOGP, rather than HID if Hid-over-GATT service is found but not HID service on the remote device." am: 06829ebd am: b72746f0 am: c77647bb

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2472864



Change-Id: Ia98db34c978bd740a0ab94810bee66b5e87f511d
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents f5a83593 c77647bb
Loading
Loading
Loading
Loading
+147 −62
Original line number Diff line number Diff line
@@ -33,13 +33,16 @@
#include "bta/include/bta_hh_api.h"
#include "bta/include/bta_hh_co.h"
#include "bta/sys/bta_sys.h"
#include "btif/include/btif_storage.h"
#include "main/shim/dumpsys.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"  // UNUSED_ATTR
#include "stack/include/acl_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/hiddefs.h"
#include "stack/include/hidh_api.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"

/*****************************************************************************
@@ -315,77 +318,38 @@ static void bta_hh_di_sdp_cback(tSDP_RESULT result) {
 * Returns          void
 *
 ******************************************************************************/
void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
  uint8_t hdl;

  p_cb->mode = p_data->api_conn.mode;
  bta_hh_cb.p_cur = p_cb;

  if (BTM_UseLeLink(p_data->api_conn.bd_addr)) {
    p_cb->is_le_device = true;
    bta_hh_le_open_conn(p_cb, p_data->api_conn.bd_addr);
    return;
  }

  /* if previously virtually cabled device, skip SDP */
  if (p_cb->app_id) {
    status = BTA_HH_OK;
    APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__);
    if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
      if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) {
        /* update device CB with newly register device handle */
        bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL,
                                  p_cb->sub_class,
                                  p_cb->dscp_info.ssr_max_latency,
                                  p_cb->dscp_info.ssr_min_tout, p_cb->app_id);
        /* update cb_index[] map */
        bta_hh_cb.cb_index[hdl] = p_cb->index;
      } else
        status = BTA_HH_ERR_NO_RES;
    }
    tBTA_HH_DATA bta_hh_data;
    bta_hh_data.status = status;
    bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);

    return;
  }
  /* GetSDPRecord. at one time only one SDP precedure can be active */
  else if (!bta_hh_cb.p_disc_db) {
static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  if (!bta_hh_cb.p_disc_db) {
    bta_hh_cb.p_disc_db =
        (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size);
    bta_hh_cb.p_cur = p_cb;
    /* do DI discovery first */

    /* Do DI discovery first */
    if (SDP_DiDiscover(p_data->api_conn.bd_addr, bta_hh_cb.p_disc_db,
                       p_bta_hh_cfg->sdp_db_size,
                       bta_hh_di_sdp_cback) != SDP_SUCCESS) {
      APPL_TRACE_DEBUG("%s:  SDP_DiDiscover failed: Status 0x%2X", __func__,
                       status);
      status = BTA_HH_ERR_SDP;
      osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
                       bta_hh_di_sdp_cback) == SDP_SUCCESS) {
      /* SDP search started successfully
       * Connection will be triggered at the end of successful SDP search
       */
    } else {
      status = BTA_HH_OK;
      LOG_ERROR("SDP_DiDiscover failed");

      osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);

      tBTA_HH_DATA bta_hh_data;
      bta_hh_data.status = BTA_HH_ERR_SDP;
      bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
    }
  } else if (bta_hh_cb.p_disc_db) {
    /* It is possible that there is incoming/outgoing collision case. DUT
     * initiated
     * HID connection at same time remote has connected L2CAP for HID control,
     * so SDP would be in progress, when this flow reaches here. Just do nothing
     * when the code reaches here, and ongoing SDP completion or failure will
     * handle this case.
    /* Incoming/outgoing collision case. DUT initiated HID connection at the
     * same time as the remote connected HID control channel.
     * When flow reaches here due to remote initiated connection, DUT may be
     * doing SDP. In such case, just do nothing and the ongoing SDP completion
     * or failure will handle this case.
     */
    APPL_TRACE_DEBUG("%s: ignoring as SDP already in progress", __func__);
    return;
    LOG_WARN("Ignoring as SDP already in progress");
  }

  if (status != BTA_HH_OK) {
    tBTA_HH_DATA bta_hh_data;
    bta_hh_data.status = status;
    bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
}

  return;
}
/*******************************************************************************
 *
 * Function         bta_hh_sdp_cmpl
@@ -470,6 +434,126 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  return;
}

/*******************************************************************************
 *
 * Function         bta_hh_bredr_conn
 *
 * Description      Initiate BR/EDR HID connection. This may be triggered by
 *                  the local application or as a result of remote initiated
 *                  HID connection.
 *
 * Returns          void
 *
 ******************************************************************************/
static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  bta_hh_cb.p_cur = p_cb;

  /* If previously virtually cabled device */
  if (p_cb->app_id) {
    tBTA_HH_DATA bta_hh_data;
    bta_hh_data.status = BTA_HH_OK;

    APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__);

    if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
      uint8_t hdl;
      if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) {
        /* update device CB with newly register device handle */
        bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL,
                                  p_cb->sub_class,
                                  p_cb->dscp_info.ssr_max_latency,
                                  p_cb->dscp_info.ssr_min_tout, p_cb->app_id);
        /* update cb_index[] map */
        bta_hh_cb.cb_index[hdl] = p_cb->index;
      } else {
        bta_hh_data.status = BTA_HH_ERR_NO_RES;
      }
    }

    bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
  }
  else { /* First time connection, start SDP */
    bta_hh_start_sdp(p_cb, p_data);
  }
}

/*******************************************************************************
 *
 * Function         bta_hh_connect
 *
 * Description      Start HID host connection.
 *
 * Returns          void
 *
 ******************************************************************************/
void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  bool hid_available = false;
  bool hogp_available = false;
  bluetooth::Uuid remote_uuids[BT_MAX_NUM_UUIDS] = {};
  bt_property_t remote_properties = {BT_PROPERTY_UUIDS, sizeof(remote_uuids),
                                     &remote_uuids};
  const RawAddress& bd_addr = p_data->api_conn.bd_addr;

  // Find the device type
  tBT_DEVICE_TYPE dev_type;
  tBLE_ADDR_TYPE addr_type;
  BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);

  // Find which transports are already connected
  bool bredr = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR);
  bool le_acl = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE);

  // Find which services known to be available
  if (btif_storage_get_remote_device_property(&bd_addr,
                                              &remote_properties) == BT_STATUS_SUCCESS) {
    int count = remote_properties.len / sizeof(remote_uuids[0]);
    for (int i = 0; i < count; i++) {
      if (remote_uuids[i].Is16Bit()) {
        if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_HUMAN_INTERFACE) {
          hid_available = true;
        } else if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_LE_HID) {
          hogp_available = true;
        }
      }

      if (hid_available && hogp_available) {
        break;
      }
    }
  }

  /* Decide whether to connect HID or HOGP */
  if (bredr && hid_available) {
    p_cb->is_le_device = false;
  } else if (le_acl && hogp_available) {
    p_cb->is_le_device = true;
  } else if (hid_available) {
    p_cb->is_le_device = false;
  } else if (hogp_available) {
    p_cb->is_le_device = true;
  } else if (bredr) {
    p_cb->is_le_device = false;
  } else if (le_acl || dev_type == BT_DEVICE_TYPE_BLE) {
    p_cb->is_le_device = true;
  } else {
    p_cb->is_le_device = false;
  }

  LOG_DEBUG("bd_addr:%s, bredr:%d, hid_available:%d, le_acl:%d, hogp_available:%d, "
            "dev_type:%d, is_le_device:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bredr,
            hid_available, le_acl, hogp_available, dev_type, p_cb->is_le_device);

  p_cb->mode = p_data->api_conn.mode;
  bta_hh_cb.p_cur = p_cb;

  // Initiate HID host connection
  if (p_cb->is_le_device) {
    bta_hh_le_open_conn(p_cb, bd_addr);
  } else {
    bta_hh_bredr_conn(p_cb, p_data);
  }
}

/*******************************************************************************
 *
 * Function         bta_hh_api_disc_act
@@ -603,7 +687,8 @@ void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {

    memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN));
    conn_data.bd_addr = p_cb->addr;
    bta_hh_start_sdp(p_cb, (tBTA_HH_DATA*)&conn_data);
    bta_hh_cb.p_cur = p_cb;
    bta_hh_bredr_conn(p_cb, (tBTA_HH_DATA*)&conn_data);
  }

  return;
+1 −1
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ extern void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
extern void bta_hh_data_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
extern void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb,
                                const tBTA_HH_DATA* p_data);
extern void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
extern void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
extern void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
extern void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb,
                                 const tBTA_HH_DATA* p_data);
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event,
      switch (event) {
        case BTA_HH_API_OPEN_EVT:
          p_cb->state = BTA_HH_W4_CONN_ST;
          bta_hh_start_sdp(p_cb, p_data);
          bta_hh_connect(p_cb, p_data);
          break;
        case BTA_HH_INT_OPEN_EVT:
          p_cb->state = BTA_HH_W4_CONN_ST;