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

Commit 4cbf4087 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "RootCanal: Add LE Parameter Updates"

parents 3305bc02 94617005
Loading
Loading
Loading
Loading
+43 −4
Original line number Diff line number Diff line
@@ -226,6 +226,10 @@ DualModeController::DualModeController(const std::string& properties_filename, u
  SET_SUPPORTED(LE_RAND, LeRand);
  SET_SUPPORTED(LE_READ_SUPPORTED_STATES, LeReadSupportedStates);
  SET_HANDLER(LE_GET_VENDOR_CAPABILITIES, LeVendorCap);
  SET_HANDLER(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY,
              LeRemoteConnectionParameterRequestReply);
  SET_HANDLER(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY,
              LeRemoteConnectionParameterRequestNegativeReply);
  SET_HANDLER(LE_MULTI_ADVT, LeVendorMultiAdv);
  SET_HANDLER(LE_ADV_FILTER, LeAdvertisingFilter);
  SET_HANDLER(LE_ENERGY_INFO, LeEnergyInfo);
@@ -1794,11 +1798,13 @@ void DualModeController::LeConnectionUpdate(CommandView command) {
      gd_hci::LeConnectionManagementCommandView::Create(
          gd_hci::AclCommandView::Create(command)));
  ASSERT(command_view.IsValid());
  ErrorCode status = link_layer_controller_.LeConnectionUpdate(command_view);
  ErrorCode status = link_layer_controller_.LeConnectionUpdate(
      command_view.GetConnectionHandle(), command_view.GetConnIntervalMin(),
      command_view.GetConnIntervalMax(), command_view.GetConnLatency(),
      command_view.GetSupervisionTimeout());

  auto status_packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
      status, kNumCommandPackets);
  send_event_(std::move(status_packet));
  send_event_(bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
      status, kNumCommandPackets));
}

void DualModeController::CreateConnection(CommandView command) {
@@ -2320,6 +2326,39 @@ void DualModeController::LeReadSupportedStates(CommandView command) {
  send_event_(std::move(packet));
}

void DualModeController::LeRemoteConnectionParameterRequestReply(
    CommandView command) {
  auto command_view =
      gd_hci::LeRemoteConnectionParameterRequestReplyView::Create(
          gd_hci::LeConnectionManagementCommandView::Create(
              gd_hci::AclCommandView::Create(command)));
  ASSERT(command_view.IsValid());
  auto status = link_layer_controller_.LeRemoteConnectionParameterRequestReply(
      command_view.GetConnectionHandle(), command_view.GetIntervalMin(),
      command_view.GetIntervalMax(), command_view.GetTimeout(),
      command_view.GetLatency(), command_view.GetMinimumCeLength(),
      command_view.GetMaximumCeLength());
  send_event_(
      gd_hci::LeRemoteConnectionParameterRequestReplyCompleteBuilder::Create(
          kNumCommandPackets, status, command_view.GetConnectionHandle()));
}

void DualModeController::LeRemoteConnectionParameterRequestNegativeReply(
    CommandView command) {
  auto command_view =
      gd_hci::LeRemoteConnectionParameterRequestNegativeReplyView::Create(
          gd_hci::LeConnectionManagementCommandView::Create(
              gd_hci::AclCommandView::Create(command)));
  ASSERT(command_view.IsValid());
  auto status =
      link_layer_controller_.LeRemoteConnectionParameterRequestNegativeReply(
          command_view.GetConnectionHandle(), command_view.GetReason());
  send_event_(
      gd_hci::LeRemoteConnectionParameterRequestNegativeReplyCompleteBuilder::
          Create(kNumCommandPackets, status,
                 command_view.GetConnectionHandle()));
}

void DualModeController::LeVendorCap(CommandView command) {
  auto command_view = gd_hci::LeGetVendorCapabilitiesView::Create(
      gd_hci::VendorCommandView::Create(command));
+6 −0
Original line number Diff line number Diff line
@@ -465,6 +465,12 @@ class DualModeController : public Device {
  // 7.8.27
  void LeReadSupportedStates(CommandView args);

  // 7.8.31
  void LeRemoteConnectionParameterRequestReply(CommandView args);

  // 7.8.32
  void LeRemoteConnectionParameterRequestNegativeReply(CommandView args);

  // 7.8.34
  void LeReadSuggestedDefaultDataLength(CommandView args);

+105 −12
Original line number Diff line number Diff line
@@ -287,6 +287,12 @@ void LinkLayerController::IncomingPacket(
    case model::packets::PacketType::LE_CONNECT_COMPLETE:
      IncomingLeConnectCompletePacket(incoming);
      break;
    case model::packets::PacketType::LE_CONNECTION_PARAMETER_REQUEST:
      IncomingLeConnectionParameterRequest(incoming);
      break;
    case model::packets::PacketType::LE_CONNECTION_PARAMETER_UPDATE:
      IncomingLeConnectionParameterUpdate(incoming);
      break;
    case model::packets::PacketType::LE_ENCRYPT_CONNECTION:
      IncomingLeEncryptConnection(incoming);
      break;
@@ -1399,6 +1405,51 @@ void LinkLayerController::IncomingLeConnectCompletePacket(
      complete.GetLeConnectionSupervisionTimeout());
}

void LinkLayerController::IncomingLeConnectionParameterRequest(
    model::packets::LinkLayerPacketView incoming) {
  auto request =
      model::packets::LeConnectionParameterRequestView::Create(incoming);
  ASSERT(request.IsValid());
  Address peer = incoming.GetSourceAddress();
  uint16_t handle = connections_.GetHandleOnlyAddress(peer);
  if (handle == kReservedHandle) {
    LOG_INFO("@%s: Unknown connection @%s",
             incoming.GetDestinationAddress().ToString().c_str(),
             peer.ToString().c_str());
    return;
  }
  if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
      properties_.GetLeEventSupported(
          bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
    send_event_(
        bluetooth::hci::LeRemoteConnectionParameterRequestBuilder::Create(
            handle, request.GetIntervalMin(), request.GetIntervalMax(),
            request.GetLatency(), request.GetTimeout()));
  }
}

void LinkLayerController::IncomingLeConnectionParameterUpdate(
    model::packets::LinkLayerPacketView incoming) {
  auto update =
      model::packets::LeConnectionParameterUpdateView::Create(incoming);
  ASSERT(update.IsValid());
  Address peer = incoming.GetSourceAddress();
  uint16_t handle = connections_.GetHandleOnlyAddress(peer);
  if (handle == kReservedHandle) {
    LOG_INFO("@%s: Unknown connection @%s",
             incoming.GetDestinationAddress().ToString().c_str(),
             peer.ToString().c_str());
    return;
  }
  if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
      properties_.GetLeEventSupported(
          bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
    send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
        static_cast<ErrorCode>(update.GetStatus()), handle,
        update.GetInterval(), update.GetLatency(), update.GetTimeout()));
  }
}

void LinkLayerController::IncomingLeEncryptConnection(
    model::packets::LinkLayerPacketView incoming) {
  LOG_INFO("IncomingLeEncryptConnection");
@@ -2735,16 +2786,12 @@ ErrorCode LinkLayerController::LeClearAdvertisingSets() {
}

void LinkLayerController::LeConnectionUpdateComplete(
    bluetooth::hci::LeConnectionUpdateView connection_update) {
  uint16_t handle = connection_update.GetConnectionHandle();
    uint16_t handle, uint16_t interval_min, uint16_t interval_max,
    uint16_t latency, uint16_t supervision_timeout) {
  ErrorCode status = ErrorCode::SUCCESS;
  if (!connections_.HasHandle(handle)) {
    status = ErrorCode::UNKNOWN_CONNECTION;
  }
  uint16_t interval_min = connection_update.GetConnIntervalMin();
  uint16_t interval_max = connection_update.GetConnIntervalMax();
  uint16_t latency = connection_update.GetConnLatency();
  uint16_t supervision_timeout = connection_update.GetSupervisionTimeout();

  if (interval_min < 6 || interval_max > 0xC80 || interval_min > interval_max ||
      interval_max < interval_min || latency > 0x1F3 ||
@@ -2755,24 +2802,70 @@ void LinkLayerController::LeConnectionUpdateComplete(
    status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  }
  uint16_t interval = (interval_min + interval_max) / 2;
  if (properties_.IsUnmasked(EventCode::LE_META_EVENT)) {

  SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
      connections_.GetOwnAddress(handle).GetAddress(),
      connections_.GetAddress(handle).GetAddress(),
      static_cast<uint8_t>(ErrorCode::SUCCESS), interval, latency,
      supervision_timeout));

  if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
      properties_.GetLeEventSupported(
          bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
    send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
        status, handle, interval, latency, supervision_timeout));
  }
}

ErrorCode LinkLayerController::LeConnectionUpdate(
    bluetooth::hci::LeConnectionUpdateView connection_update) {
  uint16_t handle = connection_update.GetConnectionHandle();
    uint16_t handle, uint16_t interval_min, uint16_t interval_max,
    uint16_t latency, uint16_t supervision_timeout) {
  if (!connections_.HasHandle(handle)) {
    return ErrorCode::UNKNOWN_CONNECTION;
  }

  // This could negotiate with the remote device in the future
  ScheduleTask(milliseconds(25), [this, connection_update]() {
    LeConnectionUpdateComplete(connection_update);
  SendLeLinkLayerPacket(LeConnectionParameterRequestBuilder::Create(
      connections_.GetOwnAddress(handle).GetAddress(),
      connections_.GetAddress(handle).GetAddress(), interval_min, interval_max,
      latency, supervision_timeout));

  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestReply(
    uint16_t connection_handle, uint16_t interval_min, uint16_t interval_max,
    uint16_t timeout, uint16_t latency, uint16_t minimum_ce_length,
    uint16_t maximum_ce_length) {
  if (!connections_.HasHandle(connection_handle)) {
    return ErrorCode::UNKNOWN_CONNECTION;
  }

  if ((interval_min > interval_max) ||
      (minimum_ce_length > maximum_ce_length)) {
    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  }

  ScheduleTask(milliseconds(25), [this, connection_handle, interval_min,
                                  interval_max, latency, timeout]() {
    LeConnectionUpdateComplete(connection_handle, interval_min, interval_max,
                               latency, timeout);
  });
  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestNegativeReply(
    uint16_t connection_handle, bluetooth::hci::ErrorCode reason) {
  if (!connections_.HasHandle(connection_handle)) {
    return ErrorCode::UNKNOWN_CONNECTION;
  }

  uint16_t interval = 0;
  uint16_t latency = 0;
  uint16_t timeout = 0;
  SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
      connections_.GetOwnAddress(connection_handle).GetAddress(),
      connections_.GetAddress(connection_handle).GetAddress(),
      static_cast<uint8_t>(reason), interval, latency, timeout));
  return ErrorCode::SUCCESS;
}

+16 −5
Original line number Diff line number Diff line
@@ -157,11 +157,18 @@ class LinkLayerController {
      bluetooth::hci::AdvertisingFilterPolicy filter_policy);
  ErrorCode LeRemoveAdvertisingSet(uint8_t set);
  ErrorCode LeClearAdvertisingSets();
  void LeConnectionUpdateComplete(
      bluetooth::hci::LeConnectionUpdateView connection_update_view);
  ErrorCode LeConnectionUpdate(
      bluetooth::hci::LeConnectionUpdateView connection_update_view);

  void LeConnectionUpdateComplete(uint16_t handle, uint16_t interval_min,
                                  uint16_t interval_max, uint16_t latency,
                                  uint16_t supervision_timeout);
  ErrorCode LeConnectionUpdate(uint16_t handle, uint16_t interval_min,
                               uint16_t interval_max, uint16_t latency,
                               uint16_t supervision_timeout);
  ErrorCode LeRemoteConnectionParameterRequestReply(
      uint16_t connection_handle, uint16_t interval_min, uint16_t interval_max,
      uint16_t timeout, uint16_t latency, uint16_t minimum_ce_length,
      uint16_t maximum_ce_length);
  ErrorCode LeRemoteConnectionParameterRequestNegativeReply(
      uint16_t connection_handle, bluetooth::hci::ErrorCode reason);
  uint16_t HandleLeConnection(AddressWithType addr, AddressWithType own_addr,
                              uint8_t role, uint16_t connection_interval,
                              uint16_t connection_latency,
@@ -371,6 +378,10 @@ class LinkLayerController {
  void IncomingLeConnectPacket(model::packets::LinkLayerPacketView packet);
  void IncomingLeConnectCompletePacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeConnectionParameterRequest(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeConnectionParameterUpdate(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeEncryptConnection(model::packets::LinkLayerPacketView packet);
  void IncomingLeEncryptConnectionResponse(
      model::packets::LinkLayerPacketView packet);
+16 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ enum PacketType : 8 {
    PIN_RESPONSE = 0x2B,
    LE_READ_REMOTE_FEATURES = 0x2C,
    LE_READ_REMOTE_FEATURES_RESPONSE = 0x2D,
    LE_CONNECTION_PARAMETER_REQUEST = 0x2E,
    LE_CONNECTION_PARAMETER_UPDATE = 0x2F,
}

packet LinkLayerPacket {
@@ -361,3 +363,17 @@ packet LeReadRemoteFeaturesResponse : LinkLayerPacket (type = LE_READ_REMOTE_FEA
  features : 64,
  status : 8,
}

packet LeConnectionParameterRequest : LinkLayerPacket (type = LE_CONNECTION_PARAMETER_REQUEST) {
  interval_min : 16,
  interval_max : 16,
  latency : 16,
  timeout : 16,
}

packet LeConnectionParameterUpdate : LinkLayerPacket (type = LE_CONNECTION_PARAMETER_UPDATE) {
  status : 8,
  interval : 16,
  latency : 16,
  timeout : 16,
}