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

Commit de94e7ed authored by Brian Delwiche's avatar Brian Delwiche Committed by Android (Google) Code Review
Browse files

Merge "RESTRICT AUTOMERGE Disallow unexpected incoming HID connections" into udc-dev

parents db5db04c bdd92020
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -282,7 +282,8 @@ static jboolean connectHidNative(JNIEnv* env, jobject object,
}

static jboolean disconnectHidNative(JNIEnv* env, jobject object,
                                    jbyteArray address) {
                                    jbyteArray address,
                                    jboolean reconnect_allowed) {
  jbyte* addr;
  jboolean ret = JNI_TRUE;
  if (!sBluetoothHidInterface) return JNI_FALSE;
@@ -293,7 +294,8 @@ static jboolean disconnectHidNative(JNIEnv* env, jobject object,
    return JNI_FALSE;
  }

  bt_status_t status = sBluetoothHidInterface->disconnect((RawAddress*)addr);
  bt_status_t status =
      sBluetoothHidInterface->disconnect((RawAddress*)addr, reconnect_allowed);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed disconnect hid channel, status: %d", status);
    ret = JNI_FALSE;
@@ -509,7 +511,7 @@ static JNINativeMethod sMethods[] = {
    {"initializeNative", "()V", (void*)initializeNative},
    {"cleanupNative", "()V", (void*)cleanupNative},
    {"connectHidNative", "([B)Z", (void*)connectHidNative},
    {"disconnectHidNative", "([B)Z", (void*)disconnectHidNative},
    {"disconnectHidNative", "([BZ)Z", (void*)disconnectHidNative},
    {"getProtocolModeNative", "([B)Z", (void*)getProtocolModeNative},
    {"virtualUnPlugNative", "([B)Z", (void*)virtualUnPlugNative},
    {"setProtocolModeNative", "([BB)Z", (void*)setProtocolModeNative},
+6 −5
Original line number Diff line number Diff line
@@ -190,7 +190,10 @@ public class HidHostService extends ProfileService {
                break;
                case MESSAGE_DISCONNECT: {
                    BluetoothDevice device = (BluetoothDevice) msg.obj;
                    if (!disconnectHidNative(getByteAddress(device))) {
                    int connectionPolicy = getConnectionPolicy(device);
                    boolean reconnectAllowed =
                            connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED;
                    if (!disconnectHidNative(getByteAddress(device), reconnectAllowed)) {
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING);
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED);
                        break;
@@ -326,9 +329,7 @@ public class HidHostService extends ProfileService {
        }
    };

    /**
     * Handlers for incoming service calls
     */
    /** Handlers for incoming service calls */
    @VisibleForTesting
    static class BluetoothHidHostBinder extends IBluetoothHidHost.Stub
            implements IProfileServiceBinder {
@@ -1032,7 +1033,7 @@ public class HidHostService extends ProfileService {

    private native boolean connectHidNative(byte[] btAddress);

    private native boolean disconnectHidNative(byte[] btAddress);
    private native boolean disconnectHidNative(byte[] btAddress, boolean reconnect_allowed);

    private native boolean getProtocolModeNative(byte[] btAddress);

+3 −1
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ typedef struct {
  uint8_t dev_handle;
  RawAddress bd_addr;
  tBTA_HH_ATTR_MASK attr_mask;
  bool reconnect_allowed;
} btif_hh_added_device_t;

/**
@@ -134,7 +135,8 @@ extern btif_hh_cb_t btif_hh_cb;

btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle);
void btif_hh_remove_device(RawAddress bd_addr);
bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask);
bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask,
                           bool reconnect_allowed);
bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr);
void btif_hh_disconnect(RawAddress* bd_addr);
void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
+23 −0
Original line number Diff line number Diff line
@@ -216,6 +216,29 @@ void btif_storage_load_le_devices(void);
 ******************************************************************************/
bt_status_t btif_storage_load_bonded_devices(void);

/*******************************************************************************
 *
 * Function         btif_storage_set_hid_connection_policy
 *
 * Description      Stores connection policy info in nvram
 *
 * Returns          BT_STATUS_SUCCESS
 *
 ******************************************************************************/
bt_status_t btif_storage_set_hid_connection_policy(const RawAddress& addr,
                                                   bool reconnect_allowed);
/*******************************************************************************
 *
 * Function         btif_storage_get_hid_connection_policy
 *
 * Description      get connection policy info from nvram
 *
 * Returns          BT_STATUS_SUCCESS
 *
 ******************************************************************************/
bt_status_t btif_storage_get_hid_connection_policy(const RawAddress& addr,
                                                   bool* reconnect_allowed);

/*******************************************************************************
 *
 * Function         btif_storage_add_hid_device_info
+76 −5
Original line number Diff line number Diff line
@@ -309,6 +309,24 @@ btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle) {
  return NULL;
}

/*******************************************************************************
 *
 * Function         btif_hh_find_added_dev
 *
 * Description      Return the added device pointer of the specified address
 *
 * Returns          Added device entry
 ******************************************************************************/
btif_hh_added_device_t* btif_hh_find_added_dev(const RawAddress& addr) {
  for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    btif_hh_added_device_t* added_dev = &btif_hh_cb.added_devices[i];
    if (added_dev->bd_addr == addr) {
      return added_dev;
    }
  }
  return nullptr;
}

/*******************************************************************************
 *
 * Function         btif_hh_find_dev_by_bda
@@ -398,9 +416,38 @@ static void hh_connect_complete(uint8_t handle, RawAddress& bda,
  HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bda, state);
}

static bool hh_connection_allowed(const RawAddress& bda) {
  /* Accept connection only if reconnection is allowed for the known device, or
   * outgoing connection was requested */
  btif_hh_added_device_t* added_dev = btif_hh_find_added_dev(bda);
  if (added_dev != nullptr && added_dev->reconnect_allowed) {
    LOG_VERBOSE("Connection allowed %s", ADDRESS_TO_LOGGABLE_CSTR(bda));
    return true;
  } else if (btif_hh_cb.pending_conn_address == bda) {
    LOG_VERBOSE("Device connection was pending for: %s, status: %s",
                ADDRESS_TO_LOGGABLE_CSTR(bda),
                btif_hh_status_text(btif_hh_cb.status).c_str());
    return true;
  }

  return false;
}

static void hh_open_handler(tBTA_HH_CONN& conn) {
  LOG_DEBUG("status = %d, handle = %d", conn.status, conn.handle);

  if (!hh_connection_allowed(conn.bda)) {
    LOG_WARN("Reject unexpected incoming HID Connection, device: %s",
             ADDRESS_TO_LOGGABLE_CSTR(conn.bda));
    btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_handle(conn.handle);
    if (p_dev != nullptr) {
      p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
    }

    hh_connect_complete(conn.handle, conn.bda, BTIF_HH_DEV_DISCONNECTED);
    return;
  }

  HAL_CBACK(bt_hh_callbacks, connection_state_cb, (RawAddress*)&conn.bda,
            BTHH_CONN_STATE_CONNECTING);
  btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
@@ -454,7 +501,8 @@ static void hh_open_handler(tBTA_HH_CONN& conn) {
 *
 * Returns          true if add successfully, otherwise false.
 ******************************************************************************/
bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask) {
bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask,
                           bool reconnect_allowed) {
  int i;
  for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    if (btif_hh_cb.added_devices[i].bd_addr == bda) {
@@ -464,10 +512,12 @@ bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask) {
  }
  for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    if (btif_hh_cb.added_devices[i].bd_addr.IsEmpty()) {
      LOG(WARNING) << " Added device " << ADDRESS_TO_LOGGABLE_STR(bda);
      LOG(WARNING) << " Added device " << ADDRESS_TO_LOGGABLE_STR(bda)
                   << " reconnection allowed: " << reconnect_allowed;
      btif_hh_cb.added_devices[i].bd_addr = bda;
      btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
      btif_hh_cb.added_devices[i].attr_mask = attr_mask;
      btif_hh_cb.added_devices[i].reconnect_allowed = reconnect_allowed;
      return true;
    }
  }
@@ -1025,7 +1075,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
                                p_data->dscp_info.version,
                                p_data->dscp_info.ctry_code, len,
                                p_data->dscp_info.descriptor.dsc_list);
        if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
        if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask, true)) {
          tBTA_HH_DEV_DSCP_INFO dscp_info;
          bt_status_t ret;
          btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
@@ -1042,6 +1092,8 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
              p_data->dscp_info.ssr_min_tout, len,
              p_data->dscp_info.descriptor.dsc_list);

          btif_storage_set_hid_connection_policy(p_dev->bd_addr, true);

          ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret);
          BTIF_TRACE_WARNING("BTA_HH_GET_DSCP_EVT: Called add device");

@@ -1341,12 +1393,20 @@ static bt_status_t connect(RawAddress* bd_addr) {
    return BT_STATUS_NOT_READY;
  }

  /* If the device was already added, ensure that reconnections are allowed */
  btif_hh_added_device_t* added_dev = btif_hh_find_added_dev(*bd_addr);
  if (added_dev != nullptr && !added_dev->reconnect_allowed) {
    added_dev->reconnect_allowed = true;
    btif_storage_set_hid_connection_policy(*bd_addr, true);
  }

  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
  if (p_dev) {
    if (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED ||
        p_dev->dev_status == BTHH_CONN_STATE_CONNECTING) {
      BTIF_TRACE_ERROR("%s: Error, device %s already connected.", __func__,
                       ADDRESS_TO_LOGGABLE_CSTR(*bd_addr));

      return BT_STATUS_DONE;
    } else if (p_dev->dev_status == BTHH_CONN_STATE_DISCONNECTING) {
      BTIF_TRACE_ERROR("%s: Error, device %s is busy with (dis)connecting.",
@@ -1368,7 +1428,7 @@ static bt_status_t connect(RawAddress* bd_addr) {
 * Returns         bt_status_t
 *
 ******************************************************************************/
static bt_status_t disconnect(RawAddress* bd_addr) {
static bt_status_t disconnect(RawAddress* bd_addr, bool reconnect_allowed) {
  CHECK_BTHH_INIT();
  BTIF_TRACE_EVENT("BTHH: %s", __func__);
  btif_hh_device_t* p_dev;
@@ -1380,6 +1440,16 @@ static bt_status_t disconnect(RawAddress* bd_addr) {
    return BT_STATUS_UNHANDLED;
  }

  if (!reconnect_allowed) {
    LOG_INFO("Incoming reconnections disabled for device %s",
             ADDRESS_TO_LOGGABLE_CSTR(*bd_addr));
    btif_hh_added_device_t* added_dev = btif_hh_find_added_dev(*bd_addr);
    if (added_dev != nullptr && added_dev->reconnect_allowed) {
      added_dev->reconnect_allowed = false;
      btif_storage_set_hid_connection_policy(added_dev->bd_addr, false);
    }
  }

  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
  if (!p_dev) {
    BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __func__,
@@ -1524,9 +1594,10 @@ static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) {
      (uint8_t*)osi_malloc(dscp_info.descriptor.dl_len);
  memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);

  if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) {
  if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask, true)) {
    BTA_HhAddDev(*bd_addr, hid_info.attr_mask, hid_info.sub_class,
                 hid_info.app_id, dscp_info);
    btif_storage_set_hid_connection_policy(*bd_addr, true);
  }

  osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
Loading