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

Commit 0fcfc1ab authored by Henri Chataing's avatar Henri Chataing
Browse files

Reland: Provide correct disconnection error code

As per spec:
> When the Controller receives the HCI_Disconnect command, it shall
send the HCI_Command_Status event to the Host. The
HCI_Disconnection_Complete event will occur at each Host when the
termination of the connection has completed, and on the local Host
also indicates that this command has been completed. The Reason
event parameter in the event on the local Host shall be set to the
value Connection Terminated by Local Host (0x16), while that on the
remote Host shall be set to the value of the Reason command
parameter.

This reverts commit dd1a1ba7.

Test: atest pts-bot:HID/HOS/HCE/BV-03-I
Bug: 270629675
Change-Id: I33b71ceb96ea797ff4f7ed35f75496f0be7674f5
parent 17b967b0
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -4755,7 +4755,8 @@ void LinkLayerController::Tick() {

void LinkLayerController::Close() {
  for (auto handle : connections_.GetAclHandles()) {
    Disconnect(handle, ErrorCode::CONNECTION_TIMEOUT);
    Disconnect(handle, ErrorCode::CONNECTION_TIMEOUT,
               ErrorCode::CONNECTION_TIMEOUT);
  }
}

@@ -5409,18 +5410,20 @@ void LinkLayerController::SendDisconnectionCompleteEvent(uint16_t handle,
  }
}

ErrorCode LinkLayerController::Disconnect(uint16_t handle, ErrorCode reason) {
ErrorCode LinkLayerController::Disconnect(uint16_t handle,
                                          ErrorCode host_reason,
                                          ErrorCode controller_reason) {
  if (connections_.HasScoHandle(handle)) {
    const Address remote = connections_.GetScoAddress(handle);
    LOG_INFO("Disconnecting eSCO connection with %s",
             remote.ToString().c_str());

    SendLinkLayerPacket(model::packets::ScoDisconnectBuilder::Create(
        GetAddress(), remote, static_cast<uint8_t>(reason)));
        GetAddress(), remote, static_cast<uint8_t>(host_reason)));

    connections_.Disconnect(
        handle, [this](TaskId task_id) { CancelScheduledTask(task_id); });
    SendDisconnectionCompleteEvent(handle, reason);
    SendDisconnectionCompleteEvent(handle, controller_reason);
    return ErrorCode::SUCCESS;
  }

@@ -5437,26 +5440,27 @@ ErrorCode LinkLayerController::Disconnect(uint16_t handle, ErrorCode reason) {
    uint16_t sco_handle = connections_.GetScoHandle(remote.GetAddress());
    if (sco_handle != kReservedHandle) {
      SendLinkLayerPacket(model::packets::ScoDisconnectBuilder::Create(
          GetAddress(), remote.GetAddress(), static_cast<uint8_t>(reason)));
          GetAddress(), remote.GetAddress(),
          static_cast<uint8_t>(host_reason)));

      connections_.Disconnect(
          sco_handle, [this](TaskId task_id) { CancelScheduledTask(task_id); });
      SendDisconnectionCompleteEvent(sco_handle, reason);
      SendDisconnectionCompleteEvent(sco_handle, controller_reason);
    }

    SendLinkLayerPacket(model::packets::DisconnectBuilder::Create(
        GetAddress(), remote.GetAddress(), static_cast<uint8_t>(reason)));
        GetAddress(), remote.GetAddress(), static_cast<uint8_t>(host_reason)));
  } else {
    LOG_INFO("Disconnecting LE connection with %s", remote.ToString().c_str());

    SendLeLinkLayerPacket(model::packets::DisconnectBuilder::Create(
        connections_.GetOwnAddress(handle).GetAddress(), remote.GetAddress(),
        static_cast<uint8_t>(reason)));
        static_cast<uint8_t>(host_reason)));
  }

  connections_.Disconnect(
      handle, [this](TaskId task_id) { CancelScheduledTask(task_id); });
  SendDisconnectionCompleteEvent(handle, ErrorCode(reason));
  SendDisconnectionCompleteEvent(handle, controller_reason);
#ifdef ROOTCANAL_LMP
  if (is_br_edr) {
    ASSERT(link_manager_remove_link(
@@ -6311,7 +6315,8 @@ void LinkLayerController::CheckExpiringConnection(uint16_t handle) {
  }

  if (connections_.HasLinkExpired(handle)) {
    Disconnect(handle, ErrorCode::CONNECTION_TIMEOUT);
    Disconnect(handle, ErrorCode::CONNECTION_TIMEOUT,
               ErrorCode::CONNECTION_TIMEOUT);
    return;
  }

+8 −1
Original line number Diff line number Diff line
@@ -137,7 +137,14 @@ class LinkLayerController {
                             uint8_t page_scan_mode, uint16_t clock_offset,
                             uint8_t allow_role_switch);
  ErrorCode CreateConnectionCancel(const Address& addr);
  ErrorCode Disconnect(uint16_t handle, ErrorCode reason);

  // Disconnect a link.
  // \p host_reason is taken from the Disconnect command, and sent over
  // to the remote as disconnect error. \p controller_reason is the code
  // used in the DisconnectionComplete event.
  ErrorCode Disconnect(uint16_t handle, ErrorCode host_reason,
                       ErrorCode controller_reason =
                           ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST);

  // Internal task scheduler.
  // This scheduler is driven by the tick function only,