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

Commit ccbbb207 authored by Chris Manton's avatar Chris Manton Committed by Automerger Merge Worker
Browse files

Check for valid ACL disconnect reason am: 5dcdae78

parents e03576ac 5dcdae78
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -2708,8 +2708,37 @@ void acl_disconnect_from_handle(uint16_t handle, tHCI_STATUS reason,
  acl_disconnect_after_role_switch(handle, reason, comment);
}

// BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
// 7.1.6 Disconnect command
// Only a subset of reasons are valid and will be accepted
// by the controller
bool is_disconnect_reason_valid(const tHCI_REASON& reason) {
  switch (reason) {
    case HCI_ERR_AUTH_FAILURE:
    case HCI_ERR_PEER_USER:
    case HCI_ERR_REMOTE_LOW_RESOURCE:
    case HCI_ERR_REMOTE_POWER_OFF:
    case HCI_ERR_UNSUPPORTED_REM_FEATURE:
    case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED:
    case HCI_ERR_UNACCEPT_CONN_INTERVAL:
      return true;
    default:
      break;
  }
  return false;
}

void acl_disconnect_after_role_switch(uint16_t conn_handle, tHCI_STATUS reason,
                                      std::string comment) {
  if (!is_disconnect_reason_valid(reason)) {
    LOG_WARN(
        "Controller will not accept invalid reason parameter:%s"
        " instead sending:%s",
        hci_error_code_text(reason).c_str(),
        hci_error_code_text(HCI_ERR_PEER_USER).c_str());
    reason = HCI_ERR_PEER_USER;
  }

  tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(conn_handle);
  if (p_acl == nullptr) {
    LOG_ERROR("Sending disconnect for unknown acl:%hu PLEASE FIX", conn_handle);
+20 −0
Original line number Diff line number Diff line
@@ -493,3 +493,23 @@ TEST_F(StackBtmWithInitFreeTest, wipe_secrets_and_remove) {

  wipe_secrets_and_remove(device_record);
}

bool is_disconnect_reason_valid(const tHCI_REASON& reason);
TEST_F(StackBtmWithInitFreeTest, is_disconnect_reason_valid) {
  std::set<tHCI_REASON> valid_reason_set{
      HCI_ERR_AUTH_FAILURE,
      HCI_ERR_PEER_USER,
      HCI_ERR_REMOTE_LOW_RESOURCE,
      HCI_ERR_REMOTE_POWER_OFF,
      HCI_ERR_UNSUPPORTED_REM_FEATURE,
      HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED,
      HCI_ERR_UNACCEPT_CONN_INTERVAL,
  };
  for (unsigned u = 0; u < 256; u++) {
    const tHCI_REASON reason = static_cast<tHCI_REASON>(u);
    if (valid_reason_set.count(reason))
      ASSERT_TRUE(is_disconnect_reason_valid(reason));
    else
      ASSERT_FALSE(is_disconnect_reason_valid(reason));
  }
}