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

Commit 2a2f9abb authored by Yun-Hao Chung's avatar Yun-Hao Chung Committed by Yun-hao Chung
Browse files

Floss: Handle Unknown Connection Error as if Disconnnect Complete

When conntroller replies |Unknown Connection| (0x02) error in command
status event, although it could be a controller issue, we can still
handle it as |Disconnect Complete| HCI event so that the stack could
properly cleanup the connection state.

Currently we only add this policy to |LE Read Remote Features| because
we only observe the issue on this command.

Bug: 292116133
Bug: 316928664
Test: Tested with byra/Taniks and MX Master 2S, which is a known
combination to trigger |unknown connection| described above.
Verified that after the fix, the device can be reconncted.
Test: mma -j32
Flag: EXEMPT, floss-only change

Change-Id: I2f24c2d35fd6509ba1d1c3c3b8d53410d297aa97
parent 165e1325
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -224,6 +224,24 @@ struct HciLayer::impl {
      command_queue_.front().GetCallback<TResponse>()->Invoke(std::move(response_view));
    }

#ifdef TARGET_FLOSS
    // Although UNKNOWN_CONNECTION might be a controller issue in some command status, we treat it
    // as a disconnect event to maintain consistent connection state between stack and controller
    // since there might not be further HCI Disconnect Event after this status event.
    // Currently only do this on LE_READ_REMOTE_FEATURES because it is the only one we know that
    // would return UNKNOWN_CONNECTION in some cases.
    if (op_code == OpCode::LE_READ_REMOTE_FEATURES && is_status && status_view.IsValid() &&
        status_view.GetStatus() == ErrorCode::UNKNOWN_CONNECTION) {
      auto& command_view = *command_queue_.front().command_view;
      auto le_read_features_view = bluetooth::hci::LeReadRemoteFeaturesView::Create(
          LeConnectionManagementCommandView::Create(AclCommandView::Create(command_view)));
      if (le_read_features_view.IsValid()) {
        uint16_t handle = le_read_features_view.GetConnectionHandle();
        module_.Disconnect(handle, ErrorCode::UNKNOWN_CONNECTION);
      }
    }
#endif

    command_queue_.pop_front();
    waiting_command_ = OpCode::NONE;
    if (hci_timeout_alarm_ != nullptr) {