Loading system/stack/eatt/eatt_impl.h +23 −10 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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( Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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, Loading system/stack/test/eatt/eatt_test.cc +46 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
system/stack/eatt/eatt_impl.h +23 −10 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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( Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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, Loading
system/stack/test/eatt/eatt_test.cc +46 −0 Original line number Diff line number Diff line Loading @@ -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