diff options
author | Ćukasz Rymanowski <lukasz.rymanowski@codecoup.pl> | 2021-06-21 16:44:14 +0000 |
---|---|---|
committer | Jakub Pawlowski <jpawlowski@google.com> | 2021-07-06 13:05:39 +0200 |
commit | 7d54fb0563a9b299a7fa834a54c65ccf6578323a (patch) | |
tree | f6242b30185c22b95d7eaf69910bed131f5b961b | |
parent | 8eb2d3606506055e5ab6a695881d8c8b8753c833 (diff) | |
download | bt-7d54fb0563a9b299a7fa834a54c65ccf6578323a.tar.gz |
eatt: Improve handling incoming EATT connection
With this patch we make sure that eatt_dev is created always when EATT
is supported on the peer side, no matter what is the connection role.
It will allow to accept ecoc channels when Android device is peripheral
device
Bug: 159786353
Bug: 191313013
Tag: #feature
Test: atest --host net_test_eatt
Sponsor: jpawlowski@
Merged-In: I4d735bc4a2d74f637e9c7f7819e10659af9b0fbb
Change-Id: I4d735bc4a2d74f637e9c7f7819e10659af9b0fbb
-rw-r--r-- | stack/eatt/eatt_impl.h | 29 | ||||
-rw-r--r-- | stack/test/eatt/eatt_test.cc | 40 |
2 files changed, 59 insertions, 10 deletions
diff --git a/stack/eatt/eatt_impl.h b/stack/eatt/eatt_impl.h index 5f64939d0..b61454cdf 100644 --- a/stack/eatt/eatt_impl.h +++ b/stack/eatt/eatt_impl.h @@ -571,7 +571,8 @@ struct eatt_impl { << bd_addr; } - void supported_features_cb(const RawAddress& bd_addr, uint8_t features) { + void supported_features_cb(uint8_t role, const RawAddress& bd_addr, + uint8_t features) { bool is_eatt_supported = features & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; LOG(INFO) << __func__ << " " << bd_addr @@ -579,6 +580,15 @@ struct eatt_impl { if (!is_eatt_supported) return; eatt_device* eatt_dev = add_eatt_device(bd_addr); + + if (role != HCI_ROLE_CENTRAL) { + /* TODO For now do nothing, we could run a timer here and start EATT if + * not started by central */ + LOG(INFO) + << " EATT Should be connected by the central. Let's wait for it."; + return; + } + connect_eatt(eatt_dev); } @@ -624,19 +634,18 @@ struct eatt_impl { LOG(INFO) << __func__ << " device " << bd_addr << " role" << (role == HCI_ROLE_CENTRAL ? "central" : "peripheral"); - if (role != HCI_ROLE_CENTRAL) { - /* TODO For now do nothing, we could run a timer here and start EATT if - * not started by central */ - LOG(INFO) - << " EATT Should be connected by the central. Let's wait for it."; - return; - } - if (eatt_dev) { /* We are reconnecting device we know that support EATT. * Just connect CoC */ LOG(INFO) << __func__ << " Known device, connect eCoC"; + + if (role != HCI_ROLE_CENTRAL) { + LOG(INFO) + << " EATT Should be connected by the central. Let's wait for it."; + return; + } + connect_eatt(eatt_dev); return; } @@ -644,7 +653,7 @@ struct eatt_impl { /* For new device, first read GATT server supported features. */ if (gatt_cl_read_sr_supp_feat_req( bd_addr, base::BindOnce(&eatt_impl::supported_features_cb, - base::Unretained(this))) == false) { + base::Unretained(this), role)) == false) { LOG(INFO) << __func__ << "Eatt is not supported. Checked for device " << bd_addr; } diff --git a/stack/test/eatt/eatt_test.cc b/stack/test/eatt/eatt_test.cc index b492fbd53..2a4191d08 100644 --- a/stack/test/eatt/eatt_test.cc +++ b/stack/test/eatt/eatt_test.cc @@ -179,6 +179,46 @@ TEST_F(EattTest, ConnectSucceed) { DisconnectEattDevice(connected_cids_); } +TEST_F(EattTest, IncomingEattConnectionByUnknownDevice) { + std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75}; + + EXPECT_CALL(l2cap_interface_, + ConnectCreditBasedRsp(test_address, 1, incoming_cids, + L2CAP_CONN_NO_RESOURCES, _)) + .WillOnce(Return(true)); + + l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb( + test_address, incoming_cids, BT_PSM_EATT, EATT_MIN_MTU_MPS, 1); +} + +TEST_F(EattTest, IncomingEattConnectionByKnownDevice) { + hci_role_ = HCI_ROLE_PERIPHERAL; + 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([](const RawAddress& addr) { return true; }); + + eatt_instance_->Connect(test_address); + std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75}; + + EXPECT_CALL( + l2cap_interface_, + ConnectCreditBasedRsp(test_address, 1, incoming_cids, L2CAP_CONN_OK, _)) + .WillOnce(Return(true)); + + l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb( + test_address, incoming_cids, BT_PSM_EATT, EATT_MIN_MTU_MPS, 1); + + DisconnectEattDevice(incoming_cids); + + hci_role_ = HCI_ROLE_CENTRAL; +} + TEST_F(EattTest, ReconnectInitiatedByRemoteSucceed) { ConnectDeviceEattSupported(1); DisconnectEattDevice(connected_cids_); |