1 /*
2  * Copyright 2020 HIMSA II K/S - www.himsa.dk.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <bluetooth/log.h>
19 #include <com_android_bluetooth_flags.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include <vector>
24 
25 #include "bta/test/common/fake_osi.h"
26 #include "hci/controller_interface_mock.h"
27 #include "stack/include/bt_hdr.h"
28 #include "stack/include/bt_psm_types.h"
29 #include "stack/include/l2cdefs.h"
30 #include "stack/test/common/mock_btif_storage.h"
31 #include "stack/test/common/mock_btm_api_layer.h"
32 #include "stack/test/common/mock_eatt.h"
33 #include "stack/test/common/mock_gatt_layer.h"
34 #include "stack/test/common/mock_l2cap_layer.h"
35 #include "test/mock/mock_main_shim_entry.h"
36 #include "test/mock/mock_stack_l2cap_interface.h"
37 #include "types/raw_address.h"
38 
39 // TODO(b/369381361) Enfore -Wmissing-prototypes
40 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
41 
42 using testing::_;
43 using testing::DoAll;
44 using testing::MockFunction;
45 using testing::NiceMock;
46 using testing::NotNull;
47 using testing::Return;
48 using testing::SaveArg;
49 using testing::SaveArgPointee;
50 using testing::StrictMock;
51 
52 using bluetooth::eatt::EattChannel;
53 using bluetooth::eatt::EattChannelState;
54 using namespace bluetooth;
55 
56 #define BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK 0x01
57 
58 extern struct fake_osi_alarm_set_on_mloop fake_osi_alarm_set_on_mloop_;
59 
60 /* Needed for testing context */
61 static tGATT_TCB test_tcb;
btif_storage_add_eatt_supported(const RawAddress &)62 void btif_storage_add_eatt_supported(const RawAddress& /*addr*/) { return; }
gatt_consolidate(const RawAddress &,const RawAddress &)63 void gatt_consolidate(const RawAddress& /*identity_addr*/, const RawAddress& /*rpa*/) {}
gatt_data_process(tGATT_TCB &,uint16_t,BT_HDR *)64 void gatt_data_process(tGATT_TCB& /*tcb*/, uint16_t /*cid*/, BT_HDR* /*p_buf*/) { return; }
gatt_find_tcb_by_addr(const RawAddress &,tBT_TRANSPORT)65 tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& /*bda*/, tBT_TRANSPORT /*transport*/) {
66   log::info("");
67   return &test_tcb;
68 }
69 
70 namespace {
71 const RawAddress test_address({0x11, 0x11, 0x11, 0x11, 0x11, 0x11});
72 std::vector<uint16_t> test_local_cids{61, 62, 63, 64, 65};
73 
74 class EattTest : public ::testing::Test {
75 protected:
ConnectDeviceEattSupported(int num_of_accepted_connections,bool collision=false)76   void ConnectDeviceEattSupported(int num_of_accepted_connections, bool collision = false) {
77     ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
78             .WillByDefault([](const RawAddress& addr,
79                               base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
80               std::move(cb).Run(addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
81               return true;
82             });
83     EXPECT_CALL(gatt_interface_, GetEattSupport).WillRepeatedly([](const RawAddress& /*addr*/) {
84       return true;
85     });
86 
87     EXPECT_CALL(mock_stack_l2cap_interface_,
88                 L2CA_ConnectCreditBasedReq(BT_PSM_EATT, test_address, _))
89             .WillOnce(Return(test_local_cids));
90     ON_CALL(mock_stack_l2cap_interface_, L2CA_DisconnectReq(test_local_cids[0]))
91             .WillByDefault(Return(true));
92 
93     eatt_instance_->Connect(test_address);
94 
95     if (collision) {
96       /* Collision should be handled only if all channels has been rejected in
97        * first place.*/
98       if (num_of_accepted_connections == 0) {
99         EXPECT_CALL(mock_stack_l2cap_interface_,
100                     L2CA_ConnectCreditBasedReq(BT_PSM_EATT, test_address, _))
101                 .Times(1);
102       }
103 
104       l2cap_app_info_.pL2CA_CreditBasedCollisionInd_Cb(test_address);
105     }
106 
107     int i = 0;
108     for (uint16_t cid : test_local_cids) {
109       EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
110       ASSERT_TRUE(channel != nullptr);
111       ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_PENDING);
112 
113       if (i < num_of_accepted_connections) {
114         l2cap_app_info_.pL2CA_CreditBasedConnectCfm_Cb(
115                 test_address, cid, EATT_MIN_MTU_MPS,
116                 tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK);
117         connected_cids_.push_back(cid);
118 
119         ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
120         ASSERT_TRUE(channel->tx_mtu_ == EATT_MIN_MTU_MPS);
121       } else {
122         l2cap_app_info_.pL2CA_Error_Cb(cid,
123                                        static_cast<uint16_t>(tL2CAP_CONN::L2CAP_CONN_NO_RESOURCES));
124 
125         EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
126         ASSERT_TRUE(channel == nullptr);
127       }
128       i++;
129     }
130 
131     ASSERT_TRUE(test_tcb.eatt == num_of_accepted_connections);
132   }
133 
ConnectDeviceBothSides(int num_of_accepted_connections,std::vector<uint16_t> & incoming_cids)134   void ConnectDeviceBothSides(int num_of_accepted_connections,
135                               std::vector<uint16_t>& incoming_cids) {
136     base::OnceCallback<void(const RawAddress&, uint8_t)> eatt_supp_feat_cb;
137 
138     ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
139             .WillByDefault(
140                     [&eatt_supp_feat_cb](const RawAddress& /*addr*/,
141                                          base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
142                       eatt_supp_feat_cb = std::move(cb);
143                       return true;
144                     });
145 
146     // Return false to trigger supported features request
147     ON_CALL(gatt_interface_, GetEattSupport).WillByDefault([](const RawAddress& /*addr*/) {
148       return false;
149     });
150 
151     std::vector<uint16_t> test_local_cids{61, 62, 63, 64, 65};
152     EXPECT_CALL(mock_stack_l2cap_interface_,
153                 L2CA_ConnectCreditBasedReq(BT_PSM_EATT, test_address, _))
154             .WillOnce(Return(test_local_cids));
155 
156     eatt_instance_->Connect(test_address);
157 
158     // Let the remote connect while we are trying to connect
159     EXPECT_CALL(mock_stack_l2cap_interface_,
160                 L2CA_ConnectCreditBasedRsp(test_address, 1, incoming_cids,
161                                            tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK, _))
162             .WillOnce(Return(true));
163     l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(test_address, incoming_cids, BT_PSM_EATT,
164                                                    EATT_MIN_MTU_MPS, 1);
165 
166     // Respond to feature request scheduled by the connect request
167     ASSERT_TRUE(eatt_supp_feat_cb);
168     if (eatt_supp_feat_cb) {
169       std::move(eatt_supp_feat_cb).Run(test_address, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
170     }
171 
172     int i = 0;
173     for (uint16_t cid : test_local_cids) {
174       EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
175       ASSERT_TRUE(channel != nullptr);
176       ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_PENDING);
177 
178       if (i < num_of_accepted_connections) {
179         l2cap_app_info_.pL2CA_CreditBasedConnectCfm_Cb(
180                 test_address, cid, EATT_MIN_MTU_MPS,
181                 tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK);
182         connected_cids_.push_back(cid);
183 
184         ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
185         ASSERT_TRUE(channel->tx_mtu_ == EATT_MIN_MTU_MPS);
186       } else {
187         l2cap_app_info_.pL2CA_Error_Cb(cid,
188                                        static_cast<uint16_t>(tL2CAP_CONN::L2CAP_CONN_NO_RESOURCES));
189 
190         EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
191         ASSERT_TRUE(channel == nullptr);
192       }
193       i++;
194     }
195 
196     // Check the incoming CIDs as well
197     for (auto cid : incoming_cids) {
198       EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
199       ASSERT_NE(nullptr, channel);
200       ASSERT_EQ(channel->state_, EattChannelState::EATT_CHANNEL_OPENED);
201       ASSERT_TRUE(channel->tx_mtu_ == EATT_MIN_MTU_MPS);
202     }
203 
204     ASSERT_EQ(test_tcb.eatt, num_of_accepted_connections + incoming_cids.size());
205   }
206 
DisconnectEattByPeer(void)207   void DisconnectEattByPeer(void) {
208     for (uint16_t cid : connected_cids_) {
209       l2cap_app_info_.pL2CA_DisconnectInd_Cb(cid, true);
210     }
211     ASSERT_EQ(0, test_tcb.eatt);
212   }
213 
DisconnectEattDevice(std::vector<uint16_t> cids)214   void DisconnectEattDevice(std::vector<uint16_t> cids) {
215     EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_DisconnectReq(_)).Times(cids.size());
216     eatt_instance_->Disconnect(test_address);
217 
218     ASSERT_EQ(0, test_tcb.eatt);
219   }
220 
SetUp()221   void SetUp() override {
222     bluetooth::testing::stack::l2cap::set_interface(&mock_stack_l2cap_interface_);
223     tL2CAP_APPL_INFO l2cap_callbacks{};
224 
225     le_buffer_size_.le_data_packet_length_ = 128;
226     le_buffer_size_.total_num_le_packets_ = 24;
227     EXPECT_CALL(controller_, GetLeBufferSize).WillRepeatedly(Return(le_buffer_size_));
228     bluetooth::l2cap::SetMockInterface(&l2cap_interface_);
229     bluetooth::manager::SetMockBtmApiInterface(&btm_api_interface_);
230     bluetooth::manager::SetMockBtifStorageInterface(&btif_storage_interface_);
231     bluetooth::gatt::SetMockGattInterface(&gatt_interface_);
232     bluetooth::hci::testing::mock_controller_ = &controller_;
233 
234     // Clear the static memory for each test case
235     memset(&test_tcb, 0, sizeof(test_tcb));
236 
237     EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_RegisterLECoc(BT_PSM_EATT, _, _, _))
238             .WillOnce(DoAll(SaveArg<1>(&l2cap_app_info_), ::testing::ReturnArg<0>()));
239 
240     ON_CALL(btif_storage_interface_, LoadBondedEatt).WillByDefault([]() { return; });
241 
242     hci_role_ = HCI_ROLE_CENTRAL;
243 
244     EXPECT_CALL(l2cap_interface_, LeCreditDefault()).WillRepeatedly(DoAll(Return(0xfff)));
245 
246     EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_GetBleConnRole(_))
247             .WillRepeatedly(DoAll(Return(hci_role_)));
248 
249     eatt_instance_ = EattExtension::GetInstance();
250     eatt_instance_->Start();
251 
252     Test::SetUp();
253   }
254 
TearDown()255   void TearDown() override {
256     com::android::bluetooth::flags::provider_->reset_flags();
257 
258     EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_DeregisterLECoc(BT_PSM_EATT)).Times(1);
259 
260     eatt_instance_->Stop();
261     eatt_instance_ = nullptr;
262     hci_role_ = HCI_ROLE_CENTRAL;
263     connected_cids_.clear();
264 
265     bluetooth::gatt::SetMockGattInterface(nullptr);
266     bluetooth::l2cap::SetMockInterface(nullptr);
267     bluetooth::testing::stack::l2cap::reset_interface();
268     bluetooth::manager::SetMockBtifStorageInterface(nullptr);
269     bluetooth::manager::SetMockBtmApiInterface(nullptr);
270     bluetooth::hci::testing::mock_controller_ = nullptr;
271 
272     Test::TearDown();
273   }
274 
275   tL2CAP_APPL_INFO reg_info_;
276 
277   bluetooth::manager::MockBtifStorageInterface btif_storage_interface_;
278   bluetooth::manager::MockBtmApiInterface btm_api_interface_;
279   bluetooth::l2cap::MockL2capInterface l2cap_interface_;
280   bluetooth::testing::stack::l2cap::Mock mock_stack_l2cap_interface_;
281   bluetooth::gatt::MockGattInterface gatt_interface_;
282   bluetooth::hci::testing::MockControllerInterface controller_;
283   bluetooth::hci::LeBufferSize le_buffer_size_;
284 
285   tL2CAP_APPL_INFO l2cap_app_info_;
286   EattExtension* eatt_instance_;
287   std::vector<uint16_t> connected_cids_;
288   tHCI_ROLE hci_role_ = HCI_ROLE_CENTRAL;
289 };
290 
TEST_F(EattTest,ConnectSucceed)291 TEST_F(EattTest, ConnectSucceed) {
292   ConnectDeviceEattSupported(1);
293   DisconnectEattDevice(connected_cids_);
294 }
295 
TEST_F(EattTest,IncomingEattConnectionByUnknownDevice)296 TEST_F(EattTest, IncomingEattConnectionByUnknownDevice) {
297   std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75};
298 
299   ON_CALL(btm_api_interface_, IsEncrypted)
300           .WillByDefault(
301                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return true; });
302   EXPECT_CALL(mock_stack_l2cap_interface_,
303               L2CA_ConnectCreditBasedRsp(test_address, 1, incoming_cids,
304                                          tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK, _))
305           .WillOnce(Return(true));
306 
307   l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(test_address, incoming_cids, BT_PSM_EATT,
308                                                  EATT_MIN_MTU_MPS, 1);
309 
310   DisconnectEattDevice(incoming_cids);
311 }
312 
TEST_F(EattTest,IncomingEattConnectionByKnownDevice)313 TEST_F(EattTest, IncomingEattConnectionByKnownDevice) {
314   hci_role_ = HCI_ROLE_PERIPHERAL;
315   ON_CALL(btm_api_interface_, IsEncrypted)
316           .WillByDefault(
317                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return true; });
318   ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
319           .WillByDefault([](const RawAddress& addr,
320                             base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
321             std::move(cb).Run(addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
322             return true;
323           });
324   ON_CALL(gatt_interface_, GetEattSupport).WillByDefault([](const RawAddress& /*addr*/) {
325     return true;
326   });
327 
328   eatt_instance_->Connect(test_address);
329   std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75};
330 
331   EXPECT_CALL(mock_stack_l2cap_interface_,
332               L2CA_ConnectCreditBasedRsp(test_address, 1, incoming_cids,
333                                          tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK, _))
334           .WillOnce(Return(true));
335 
336   l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(test_address, incoming_cids, BT_PSM_EATT,
337                                                  EATT_MIN_MTU_MPS, 1);
338 
339   DisconnectEattDevice(incoming_cids);
340 
341   hci_role_ = HCI_ROLE_CENTRAL;
342 }
343 
TEST_F(EattTest,IncomingEattConnectionByKnownDeviceEncryptionOff)344 TEST_F(EattTest, IncomingEattConnectionByKnownDeviceEncryptionOff) {
345   hci_role_ = HCI_ROLE_PERIPHERAL;
346   ON_CALL(btm_api_interface_, IsEncrypted)
347           .WillByDefault(
348                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return false; });
349   ON_CALL(btm_api_interface_, IsLinkKeyKnown)
350           .WillByDefault(
351                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return true; });
352   ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
353           .WillByDefault([](const RawAddress& addr,
354                             base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
355             std::move(cb).Run(addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
356             return true;
357           });
358   ON_CALL(gatt_interface_, GetEattSupport).WillByDefault([](const RawAddress& /*addr*/) {
359     return true;
360   });
361 
362   eatt_instance_->Connect(test_address);
363   std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75};
364 
365   EXPECT_CALL(
366           mock_stack_l2cap_interface_,
367           L2CA_ConnectCreditBasedRsp(test_address, 1, _,
368                                      tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP, _))
369           .WillOnce(Return(true));
370 
371   l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(test_address, incoming_cids, BT_PSM_EATT,
372                                                  EATT_MIN_MTU_MPS, 1);
373 
374   hci_role_ = HCI_ROLE_CENTRAL;
375 }
376 
TEST_F(EattTest,IncomingEattConnectionByUnknownDeviceEncryptionOff)377 TEST_F(EattTest, IncomingEattConnectionByUnknownDeviceEncryptionOff) {
378   std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75};
379 
380   ON_CALL(btm_api_interface_, IsEncrypted)
381           .WillByDefault(
382                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return false; });
383   ON_CALL(btm_api_interface_, IsLinkKeyKnown)
384           .WillByDefault(
385                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return false; });
386   EXPECT_CALL(mock_stack_l2cap_interface_,
387               L2CA_ConnectCreditBasedRsp(
388                       test_address, 1, _,
389                       tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION, _))
390           .WillOnce(Return(true));
391 
392   l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(test_address, incoming_cids, BT_PSM_EATT,
393                                                  EATT_MIN_MTU_MPS, 1);
394 }
395 
TEST_F(EattTest,ReconnectInitiatedByRemoteSucceed)396 TEST_F(EattTest, ReconnectInitiatedByRemoteSucceed) {
397   ConnectDeviceEattSupported(1);
398   DisconnectEattDevice(connected_cids_);
399   std::vector<uint16_t> incoming_cids{71, 72, 73, 74, 75};
400 
401   ON_CALL(btm_api_interface_, IsEncrypted)
402           .WillByDefault(
403                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return true; });
404 
405   EXPECT_CALL(mock_stack_l2cap_interface_,
406               L2CA_ConnectCreditBasedRsp(test_address, 1, incoming_cids,
407                                          tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK, _))
408           .WillOnce(Return(true));
409 
410   l2cap_app_info_.pL2CA_CreditBasedConnectInd_Cb(test_address, incoming_cids, BT_PSM_EATT,
411                                                  EATT_MIN_MTU_MPS, 1);
412 
413   DisconnectEattDevice(incoming_cids);
414 }
415 
TEST_F(EattTest,ConnectInitiatedWhenRemoteConnects)416 TEST_F(EattTest, ConnectInitiatedWhenRemoteConnects) {
417   ON_CALL(btm_api_interface_, IsEncrypted)
418           .WillByDefault(
419                   [](const RawAddress& /*addr*/, tBT_TRANSPORT /*transport*/) { return true; });
420 
421   std::vector<uint16_t> incoming_cids{71, 72, 73, 74};
422   ConnectDeviceBothSides(1, incoming_cids);
423 
424   std::vector<uint16_t> disconnecting_cids;
425   disconnecting_cids.insert(disconnecting_cids.end(), incoming_cids.begin(), incoming_cids.end());
426   disconnecting_cids.insert(disconnecting_cids.end(), connected_cids_.begin(),
427                             connected_cids_.end());
428   DisconnectEattDevice(disconnecting_cids);
429 }
430 
TEST_F(EattTest,ConnectSucceedMultipleChannels)431 TEST_F(EattTest, ConnectSucceedMultipleChannels) {
432   ConnectDeviceEattSupported(5);
433   DisconnectEattDevice(connected_cids_);
434 }
435 
TEST_F(EattTest,ConnectFailedEattNotSupported)436 TEST_F(EattTest, ConnectFailedEattNotSupported) {
437   ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
438           .WillByDefault([](const RawAddress& addr,
439                             base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
440             std::move(cb).Run(addr, 0);
441             return true;
442           });
443   ON_CALL(gatt_interface_, GetEattSupport).WillByDefault([](const RawAddress& /*addr*/) {
444     return false;
445   });
446 
447   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ConnectCreditBasedReq(BT_PSM_EATT, test_address, _))
448           .Times(0);
449   eatt_instance_->Connect(test_address);
450   ASSERT_TRUE(eatt_instance_->IsEattSupportedByPeer(test_address) == false);
451 }
452 
TEST_F(EattTest,ConnectFailedSlaveOnTheLink)453 TEST_F(EattTest, ConnectFailedSlaveOnTheLink) {
454   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ConnectCreditBasedReq(BT_PSM_EATT, test_address, _))
455           .Times(0);
456 
457   hci_role_ = HCI_ROLE_PERIPHERAL;
458   eatt_instance_->Connect(test_address);
459 
460   /* Back to default btm role */
461   hci_role_ = HCI_ROLE_CENTRAL;
462 }
463 
TEST_F(EattTest,DisonnectByPeerSucceed)464 TEST_F(EattTest, DisonnectByPeerSucceed) {
465   ConnectDeviceEattSupported(2);
466 
467   uint16_t cid = connected_cids_[0];
468   EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
469   ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
470 
471   DisconnectEattByPeer();
472 
473   channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
474   ASSERT_TRUE(channel == nullptr);
475 }
476 
TEST_F(EattTest,ReconfigAllSucceed)477 TEST_F(EattTest, ReconfigAllSucceed) {
478   ConnectDeviceEattSupported(3);
479 
480   std::vector<uint16_t> cids;
481   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ReconfigCreditBasedConnsReq(_, _, _))
482           .WillOnce(DoAll(SaveArg<1>(&cids), Return(true)));
483 
484   uint16_t new_mtu = 300;
485   eatt_instance_->ReconfigureAll(test_address, new_mtu);
486 
487   ASSERT_TRUE(cids.size() == connected_cids_.size());
488 
489   tL2CAP_LE_CFG_INFO cfg = {.result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, .mtu = new_mtu};
490 
491   for (uint16_t cid : cids) {
492     l2cap_app_info_.pL2CA_CreditBasedReconfigCompleted_Cb(test_address, cid, true, &cfg);
493 
494     EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
495     ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
496     ASSERT_TRUE(channel->rx_mtu_ == new_mtu);
497   }
498 
499   DisconnectEattDevice(connected_cids_);
500 }
501 
TEST_F(EattTest,ReconfigAllFailed)502 TEST_F(EattTest, ReconfigAllFailed) {
503   ConnectDeviceEattSupported(4);
504 
505   std::vector<uint16_t> cids;
506   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ReconfigCreditBasedConnsReq(_, _, _))
507           .WillOnce(DoAll(SaveArg<1>(&cids), Return(true)));
508 
509   uint16_t new_mtu = 300;
510   eatt_instance_->ReconfigureAll(test_address, new_mtu);
511 
512   ASSERT_TRUE(cids.size() == connected_cids_.size());
513 
514   tL2CAP_LE_CFG_INFO cfg = {.result = tL2CAP_CFG_RESULT::L2CAP_CFG_FAILED_NO_REASON,
515                             .mtu = new_mtu};
516 
517   for (uint16_t cid : cids) {
518     l2cap_app_info_.pL2CA_CreditBasedReconfigCompleted_Cb(test_address, cid, true, &cfg);
519 
520     EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
521     ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
522     ASSERT_TRUE(channel->rx_mtu_ != new_mtu);
523   }
524 
525   DisconnectEattDevice(connected_cids_);
526 }
527 
TEST_F(EattTest,ReconfigSingleSucceed)528 TEST_F(EattTest, ReconfigSingleSucceed) {
529   ConnectDeviceEattSupported(2);
530 
531   std::vector<uint16_t> cids;
532   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ReconfigCreditBasedConnsReq(_, _, _))
533           .WillOnce(DoAll(SaveArg<1>(&cids), Return(true)));
534 
535   uint16_t new_mtu = 300;
536   eatt_instance_->Reconfigure(test_address, connected_cids_[1], new_mtu);
537 
538   ASSERT_EQ(1U, cids.size());
539 
540   tL2CAP_LE_CFG_INFO cfg = {.result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, .mtu = new_mtu};
541 
542   auto it = std::find(connected_cids_.begin(), connected_cids_.end(), cids[0]);
543   ASSERT_TRUE(it != connected_cids_.end());
544 
545   l2cap_app_info_.pL2CA_CreditBasedReconfigCompleted_Cb(test_address, cids[0], true, &cfg);
546   EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cids[0]);
547   ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
548   ASSERT_TRUE(channel->rx_mtu_ == new_mtu);
549 
550   DisconnectEattDevice(connected_cids_);
551 }
552 
TEST_F(EattTest,ReconfigSingleFailed)553 TEST_F(EattTest, ReconfigSingleFailed) {
554   ConnectDeviceEattSupported(2);
555 
556   std::vector<uint16_t> cids;
557   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ReconfigCreditBasedConnsReq(_, _, _))
558           .WillOnce(DoAll(SaveArg<1>(&cids), Return(true)));
559 
560   uint16_t new_mtu = 300;
561   eatt_instance_->ReconfigureAll(test_address, new_mtu);
562 
563   ASSERT_TRUE(cids.size() == connected_cids_.size());
564 
565   tL2CAP_LE_CFG_INFO cfg = {.result = tL2CAP_CFG_RESULT::L2CAP_CFG_FAILED_NO_REASON,
566                             .mtu = new_mtu};
567 
568   auto it = std::find(connected_cids_.begin(), connected_cids_.end(), cids[0]);
569   ASSERT_TRUE(it != connected_cids_.end());
570 
571   l2cap_app_info_.pL2CA_CreditBasedReconfigCompleted_Cb(test_address, cids[0], true, &cfg);
572   EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cids[0]);
573   ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
574   ASSERT_TRUE(channel->rx_mtu_ != new_mtu);
575 
576   DisconnectEattDevice(connected_cids_);
577 }
578 
TEST_F(EattTest,ReconfigPeerSucceed)579 TEST_F(EattTest, ReconfigPeerSucceed) {
580   ConnectDeviceEattSupported(3);
581 
582   uint16_t new_mtu = 300;
583   tL2CAP_LE_CFG_INFO cfg = {.result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, .mtu = new_mtu};
584 
585   for (uint16_t cid : connected_cids_) {
586     l2cap_app_info_.pL2CA_CreditBasedReconfigCompleted_Cb(test_address, cid, false, &cfg);
587 
588     EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
589     ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
590     ASSERT_TRUE(channel->tx_mtu_ == new_mtu);
591   }
592 
593   DisconnectEattDevice(connected_cids_);
594 }
595 
TEST_F(EattTest,ReconfigPeerFailed)596 TEST_F(EattTest, ReconfigPeerFailed) {
597   ConnectDeviceEattSupported(2);
598 
599   uint16_t new_mtu = 300;
600   tL2CAP_LE_CFG_INFO cfg = {.result = tL2CAP_CFG_RESULT::L2CAP_CFG_FAILED_NO_REASON,
601                             .mtu = new_mtu};
602 
603   for (uint16_t cid : connected_cids_) {
604     l2cap_app_info_.pL2CA_CreditBasedReconfigCompleted_Cb(test_address, cid, false, &cfg);
605 
606     EattChannel* channel = eatt_instance_->FindEattChannelByCid(test_address, cid);
607     ASSERT_TRUE(channel->state_ == EattChannelState::EATT_CHANNEL_OPENED);
608     ASSERT_TRUE(channel->tx_mtu_ != new_mtu);
609   }
610 
611   DisconnectEattDevice(connected_cids_);
612 }
613 
TEST_F(EattTest,DoubleDisconnect)614 TEST_F(EattTest, DoubleDisconnect) {
615   ConnectDeviceEattSupported(1);
616   DisconnectEattDevice(connected_cids_);
617 
618   /* Force second disconnect */
619   eatt_instance_->Disconnect(test_address);
620 }
621 
TEST_F(EattTest,TestCollisionHandling)622 TEST_F(EattTest, TestCollisionHandling) {
623   ConnectDeviceEattSupported(0, true /* collision*/);
624   ConnectDeviceEattSupported(5, true /* collision*/);
625 }
626 
TEST_F(EattTest,ChannelUnavailableWhileOpening)627 TEST_F(EattTest, ChannelUnavailableWhileOpening) {
628   // arrange
629   ON_CALL(gatt_interface_, ClientReadSupportedFeatures)
630           .WillByDefault([](const RawAddress& addr,
631                             base::OnceCallback<void(const RawAddress&, uint8_t)> cb) {
632             std::move(cb).Run(addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK);
633             return true;
634           });
635   ON_CALL(gatt_interface_, GetEattSupport).WillByDefault(Return(true));
636 
637   // expect
638   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ConnectCreditBasedReq(BT_PSM_EATT, test_address, _))
639           .WillOnce(Return(std::vector<uint16_t>{61}));
640 
641   // act: start
642   eatt_instance_->Connect(test_address);
643   auto available_channel_for_request =
644           eatt_instance_->GetChannelAvailableForClientRequest(test_address);
645   auto available_channel_for_indication =
646           eatt_instance_->GetChannelAvailableForIndication(test_address);
647 
648   // assert
649   ASSERT_EQ(available_channel_for_request, nullptr);
650   ASSERT_EQ(available_channel_for_indication, nullptr);
651 }
652 
TEST_F(EattTest,ChannelUnavailableWhileReconfiguring)653 TEST_F(EattTest, ChannelUnavailableWhileReconfiguring) {
654   // arrange
655   ON_CALL(mock_stack_l2cap_interface_, L2CA_ReconfigCreditBasedConnsReq(_, _, _))
656           .WillByDefault(Return(true));
657   ConnectDeviceEattSupported(/* num_of_accepted_connections = */ 1);
658 
659   // act: reconfigure, then get available channels
660   eatt_instance_->Reconfigure(test_address, connected_cids_[0], 300);
661   auto available_channel_for_request =
662           eatt_instance_->GetChannelAvailableForClientRequest(test_address);
663   auto available_channel_for_indication =
664           eatt_instance_->GetChannelAvailableForIndication(test_address);
665 
666   // assert
667   ASSERT_EQ(available_channel_for_request, nullptr);
668   ASSERT_EQ(available_channel_for_indication, nullptr);
669 }
670 
TEST_F(EattTest,DisconnectChannelOnIndicationConfirmationTimeout)671 TEST_F(EattTest, DisconnectChannelOnIndicationConfirmationTimeout) {
672   com::android::bluetooth::flags::provider_->gatt_disconnect_fix(true);
673   ConnectDeviceEattSupported(1);
674 
675   eatt_instance_->StartIndicationConfirmationTimer(test_address, test_local_cids[0]);
676 
677   EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_DisconnectReq(test_local_cids[0])).Times(1);
678   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
679 }
680 
681 }  // namespace
682