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

Commit 2b65ff6c authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Don't perform operations on busy EATT channels" am: 4fcb55e1 am: 9aab81d4 am: 1c56b039

parents 318a549e 1c56b039
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