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

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

Merge "Don't perform operations on busy EATT channels"

parents 0388531f ca9331e3
Loading
Loading
Loading
Loading
+23 −10
Original line number Diff line number Diff line
@@ -434,15 +434,18 @@ struct eatt_impl {
    LOG(INFO) << __func__ << "lcid: " << loghex(lcid)
              << " local cfg?: " << is_local_cfg;

    EattChannel* channel = find_channel_by_cid(bda, lcid);
    if (!channel) return;

    // regardless of success result, we have finished reconfiguration
    channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED);

    if (p_cfg->result != L2CAP_CFG_OK) {
      LOG(INFO) << __func__ << " reconfig failed lcid: " << loghex(lcid)
                << " result: " << loghex(p_cfg->result);
      return;
    }

    EattChannel* channel = find_channel_by_cid(bda, lcid);
    if (!channel) return;

    /* On this layer we don't care about mps as this is handled in L2CAP layer
     */
    if (is_local_cfg)
@@ -450,9 +453,6 @@ struct eatt_impl {
    else
      channel->tx_mtu_ = p_cfg->mtu;

    /* Go back to open state */
    channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED);

    if (stack_config_get_interface()->get_pts_l2cap_ecoc_reconfigure()) {
      /* Upper tester for L2CAP - schedule sending data */
      do_in_main_thread_delayed(
@@ -674,7 +674,8 @@ struct eatt_impl {
    auto iter = find_if(
        eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
        [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
          return !GATT_HANDLE_IS_VALID(el.second->indicate_handle_);
          return el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED &&
                 !GATT_HANDLE_IS_VALID(el.second->indicate_handle_);
        });

    return (iter == eatt_dev->eatt_channels.end()) ? nullptr
@@ -689,7 +690,8 @@ struct eatt_impl {
    auto iter = find_if(
        eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(),
        [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) {
          return el.second->cl_cmd_q_.empty();
          return el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED &&
                 el.second->cl_cmd_q_.empty();
        });

    return (iter == eatt_dev->eatt_channels.end()) ? nullptr
@@ -826,9 +828,13 @@ struct eatt_impl {

    tL2CAP_LE_CFG_INFO cfg = {.mps = eatt_dev->rx_mps_, .mtu = new_mtu};

    if (!L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, &cfg))
    if (!L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, &cfg)) {
      LOG(ERROR) << __func__ << "Could not start reconfig cid: " << loghex(cid)
                 << " or device " << bd_addr;
      return;
    }

    channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_RECONFIGURING);
  }

  void reconfigure_all(const RawAddress& bd_addr, uint16_t new_mtu) {
@@ -862,9 +868,16 @@ struct eatt_impl {

    tL2CAP_LE_CFG_INFO cfg = {.mps = eatt_dev->rx_mps_, .mtu = new_mtu};

    if (!L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, &cfg))
    if (!L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, &cfg)) {
      LOG(ERROR) << __func__ << "Could not start reconfig for device "
                 << bd_addr;
      return;
    }

    for (auto& channel : eatt_dev->eatt_channels) {
      channel.second->EattChannelSetState(
          EattChannelState::EATT_CHANNEL_RECONFIGURING);
    }
  }

  void supported_features_cb(uint8_t role, const RawAddress& bd_addr,
+46 −0
Original line number Diff line number Diff line
@@ -624,4 +624,50 @@ TEST_F(EattTest, TestCollisionHandling) {
  ConnectDeviceEattSupported(5, true /* collision*/);
}

TEST_F(EattTest, ChannelUnavailableWhileOpening) {
  // arrange
  ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
      .WillByDefault(
          [](const RawAddress& addr,
             base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
            std::move(cb).Run(addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
            return true;
          });
  ON_CALL(gatt_interface_, GetEattSupport).WillByDefault(Return(true));

  // expect
  EXPECT_CALL(l2cap_interface_,
              ConnectCreditBasedReq(BT_PSM_EATT, test_address, _))
      .WillOnce(Return(std::vector<uint16_t>{61}));

  // act: start
  eatt_instance_->Connect(test_address);
  auto available_channel_for_request =
      eatt_instance_->GetChannelAvailableForClientRequest(test_address);
  auto available_channel_for_indication =
      eatt_instance_->GetChannelAvailableForIndication(test_address);

  // assert
  ASSERT_EQ(available_channel_for_request, nullptr);
  ASSERT_EQ(available_channel_for_indication, nullptr);
}

TEST_F(EattTest, ChannelUnavailableWhileReconfiguring) {
  // arrange
  ON_CALL(l2cap_interface_, ReconfigCreditBasedConnsReq(_, _, _))
      .WillByDefault(Return(true));
  ConnectDeviceEattSupported(/* num_of_accepted_connections = */ 1);

  // act: reconfigure, then get available channels
  eatt_instance_->Reconfigure(test_address, connected_cids_[0], 300);
  auto available_channel_for_request =
      eatt_instance_->GetChannelAvailableForClientRequest(test_address);
  auto available_channel_for_indication =
      eatt_instance_->GetChannelAvailableForIndication(test_address);

  // assert
  ASSERT_EQ(available_channel_for_request, nullptr);
  ASSERT_EQ(available_channel_for_indication, nullptr);
}

}  // namespace