• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "shim/l2cap.h"
18 
19 #include <gtest/gtest.h>
20 #include <future>
21 #include <memory>
22 
23 #include "common/bind.h"
24 #include "hci/address.h"
25 #include "hci/address_with_type.h"
26 #include "l2cap/classic/dynamic_channel_configuration_option.h"
27 #include "l2cap/classic/dynamic_channel_manager.h"
28 #include "l2cap/classic/internal/dynamic_channel_service_manager_impl_mock.h"
29 #include "l2cap/classic/l2cap_classic_module.h"
30 #include "l2cap/internal/ilink.h"
31 #include "l2cap/psm.h"
32 #include "l2cap/security_policy.h"
33 #include "os/handler.h"
34 
35 namespace bluetooth {
36 namespace shim {
37 namespace {
38 
39 constexpr uint16_t kPsm = 123;
40 constexpr uint16_t kPsm2 = kPsm + 2;
41 constexpr uint16_t kCid = 456;
42 constexpr uint16_t kCid2 = kCid + 1;
43 constexpr char device_address[] = "11:22:33:44:55:66";
44 constexpr char device_address2[] = "aa:bb:cc:dd:ee:ff";
45 constexpr bool kNoUseErtm = false;
46 constexpr uint16_t kMtu = 1000;
47 
48 class TestDynamicChannelService : public l2cap::classic::DynamicChannelService {
49  public:
TestDynamicChannelService(l2cap::Psm psm,l2cap::classic::internal::DynamicChannelServiceManagerImpl * manager,os::Handler * handler)50   TestDynamicChannelService(l2cap::Psm psm, l2cap::classic::internal::DynamicChannelServiceManagerImpl* manager,
51                             os::Handler* handler)
52       : DynamicChannelService(psm, manager, handler) {}
53 };
54 
55 class TestLink : public l2cap::internal::ILink {
56  public:
GetDevice()57   hci::AddressWithType GetDevice() {
58     return device_with_type_;
59   }
60   hci::AddressWithType device_with_type_;
61 
SendLeCredit(l2cap::Cid local_cid,uint16_t credit)62   void SendLeCredit(l2cap::Cid local_cid, uint16_t credit) {}
63 
SendDisconnectionRequest(l2cap::Cid cid,l2cap::Cid remote_cid)64   void SendDisconnectionRequest(l2cap::Cid cid, l2cap::Cid remote_cid) {
65     connection_closed_promise_.set_value();
66   }
67   std::promise<void> connection_closed_promise_;
68 };
69 
70 class TestDynamicChannelManagerImpl {
71  public:
ConnectChannel(hci::Address device,l2cap::classic::DynamicChannelConfigurationOption configuration_option,l2cap::Psm psm,l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback,os::Handler * handler)72   bool ConnectChannel(hci::Address device, l2cap::classic::DynamicChannelConfigurationOption configuration_option,
73                       l2cap::Psm psm, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,
74                       l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback,
75                       os::Handler* handler) {
76     connections_++;
77     on_open_callback_ = std::move(on_open_callback);
78     on_fail_callback_ = std::move(on_fail_callback);
79 
80     connected_promise_.set_value();
81     return true;
82   }
83   int connections_{0};
84 
RegisterService(l2cap::Psm psm,l2cap::classic::DynamicChannelConfigurationOption configuration_option,const l2cap::SecurityPolicy & security_policy,l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,os::Handler * handler)85   bool RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption configuration_option,
86                        const l2cap::SecurityPolicy& security_policy,
87                        l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,
88                        l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,
89                        os::Handler* handler) {
90     services_++;
91     on_registration_complete_ = std::move(on_registration_complete);
92     on_open_callback_ = std::move(on_open_callback);
93 
94     register_promise_.set_value();
95     return true;
96   }
97   int services_{0};
98 
SetConnectionFuture()99   void SetConnectionFuture() {
100     connected_promise_ = std::promise<void>();
101   }
102 
WaitConnectionFuture()103   void WaitConnectionFuture() {
104     connected_future_ = connected_promise_.get_future();
105     connected_future_.wait();
106   }
107 
SetRegistrationFuture()108   void SetRegistrationFuture() {
109     register_promise_ = std::promise<void>();
110   }
111 
WaitRegistrationFuture()112   void WaitRegistrationFuture() {
113     register_future_ = register_promise_.get_future();
114     register_future_.wait();
115   }
116 
SetConnectionOnFail(l2cap::classic::DynamicChannelManager::ConnectionResult result,std::promise<void> promise)117   void SetConnectionOnFail(l2cap::classic::DynamicChannelManager::ConnectionResult result, std::promise<void> promise) {
118     std::move(on_fail_callback_).Run(result);
119     promise.set_value();
120   }
121 
SetConnectionOnOpen(std::unique_ptr<l2cap::DynamicChannel> channel,std::promise<void> promise)122   void SetConnectionOnOpen(std::unique_ptr<l2cap::DynamicChannel> channel, std::promise<void> promise) {
123     std::move(on_open_callback_).Run(std::move(channel));
124     promise.set_value();
125   }
126 
127   l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete_{};
128   l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback_{};
129   l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback_{};
130 
131   TestDynamicChannelManagerImpl() = default;
132   ~TestDynamicChannelManagerImpl() = default;
133 
134  private:
135   std::promise<void> connected_promise_;
136   std::future<void> connected_future_;
137 
138   std::promise<void> register_promise_;
139   std::future<void> register_future_;
140 };
141 
142 class TestDynamicChannelManager : public l2cap::classic::DynamicChannelManager {
143  public:
ConnectChannel(hci::Address device,l2cap::classic::DynamicChannelConfigurationOption configuration_option,l2cap::Psm psm,l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback,os::Handler * handler)144   bool ConnectChannel(hci::Address device, l2cap::classic::DynamicChannelConfigurationOption configuration_option,
145                       l2cap::Psm psm, l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,
146                       l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback,
147                       os::Handler* handler) override {
148     return impl_.ConnectChannel(device, configuration_option, psm, std::move(on_open_callback),
149                                 std::move(on_fail_callback), handler);
150   }
151 
RegisterService(l2cap::Psm psm,l2cap::classic::DynamicChannelConfigurationOption configuration_option,const l2cap::SecurityPolicy & security_policy,l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,os::Handler * handler)152   bool RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption configuration_option,
153                        const l2cap::SecurityPolicy& security_policy,
154                        l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,
155                        l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,
156                        os::Handler* handler) override {
157     return impl_.RegisterService(psm, configuration_option, security_policy, std::move(on_registration_complete),
158                                  std::move(on_open_callback), handler);
159   }
TestDynamicChannelManager(TestDynamicChannelManagerImpl & impl)160   TestDynamicChannelManager(TestDynamicChannelManagerImpl& impl) : impl_(impl) {}
161   TestDynamicChannelManagerImpl& impl_;
162 };
163 
164 class TestL2capClassicModule : public l2cap::classic::L2capClassicModule {
165  public:
GetDynamicChannelManager()166   std::unique_ptr<l2cap::classic::DynamicChannelManager> GetDynamicChannelManager() override {
167     ASSERT(impl_ != nullptr);
168     return std::make_unique<TestDynamicChannelManager>(*impl_);
169   }
170 
ListDependencies(ModuleList * list)171   void ListDependencies(ModuleList* list) override {}
172   void Start() override;
173   void Stop() override;
174 
175   std::unique_ptr<TestDynamicChannelManagerImpl> impl_;
176 };
177 
Start()178 void TestL2capClassicModule::Start() {
179   impl_ = std::make_unique<TestDynamicChannelManagerImpl>();
180 }
181 
Stop()182 void TestL2capClassicModule::Stop() {
183   impl_.reset();
184 }
185 
186 class ShimL2capTest : public ::testing::Test {
187  public:
OnConnectionComplete(std::string string_address,uint16_t psm,uint16_t cid,bool connected)188   void OnConnectionComplete(std::string string_address, uint16_t psm, uint16_t cid, bool connected) {
189     connection_string_address_ = string_address;
190     connection_psm_ = psm;
191     connection_cid_ = cid;
192     connection_connected_ = connected;
193     connection_complete_promise_.set_value();
194   }
195 
CreateConnection(uint16_t psm,std::string device_address)196   uint16_t CreateConnection(uint16_t psm, std::string device_address) {
197     std::promise<uint16_t> promise;
198     auto future = promise.get_future();
199 
200     shim_l2cap_->CreateConnection(
201         psm, device_address,
202         std::bind(&bluetooth::shim::ShimL2capTest::OnConnectionComplete, this, std::placeholders::_1,
203                   std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
204         std::move(promise));
205     return future.get();
206   }
207 
SetConnectionFuture()208   void SetConnectionFuture() {
209     test_l2cap_classic_module_->impl_->SetConnectionFuture();
210   }
211 
WaitConnectionFuture()212   void WaitConnectionFuture() {
213     test_l2cap_classic_module_->impl_->WaitConnectionFuture();
214   }
215 
SetRegistrationFuture()216   void SetRegistrationFuture() {
217     test_l2cap_classic_module_->impl_->SetRegistrationFuture();
218   }
219 
WaitRegistrationFuture()220   void WaitRegistrationFuture() {
221     test_l2cap_classic_module_->impl_->WaitRegistrationFuture();
222   }
223 
NumberOfConnections() const224   int NumberOfConnections() const {
225     return test_l2cap_classic_module_->impl_->connections_;
226   }
227 
NumberOfServices() const228   int NumberOfServices() const {
229     return test_l2cap_classic_module_->impl_->services_;
230   }
231 
232   std::string connection_string_address_;
233   uint16_t connection_psm_{0};
234   uint16_t connection_cid_{0};
235   bool connection_connected_{false};
236 
237   shim::L2cap* shim_l2cap_ = nullptr;
238   TestL2capClassicModule* test_l2cap_classic_module_{nullptr};
239 
240   TestLink test_link_;
241   std::promise<void> connection_complete_promise_;
242 
243  protected:
SetUp()244   void SetUp() override {
245     handler_ = new os::Handler(&thread_);
246 
247     test_l2cap_classic_module_ = new TestL2capClassicModule();
248     test_l2cap_classic_module_->Start();
249     fake_registry_.InjectTestModule(&l2cap::classic::L2capClassicModule::Factory, test_l2cap_classic_module_);
250 
251     fake_registry_.Start<shim::L2cap>(&thread_);
252     shim_l2cap_ = static_cast<shim::L2cap*>(fake_registry_.GetModuleUnderTest(&shim::L2cap::Factory));
253   }
254 
TearDown()255   void TearDown() override {
256     fake_registry_.StopAll();
257     handler_->Clear();
258     delete handler_;
259   }
260   os::Handler* handler_ = nullptr;
261   l2cap::classic::internal::testing::MockDynamicChannelServiceManagerImpl mock_;
262 
263  private:
264   TestModuleRegistry fake_registry_;
265   os::Thread& thread_ = fake_registry_.GetTestThread();
266 };
267 
TEST_F(ShimL2capTest,CreateThenDisconnectBeforeCompletion)268 TEST_F(ShimL2capTest, CreateThenDisconnectBeforeCompletion) {
269   SetConnectionFuture();
270 
271   ASSERT(NumberOfConnections() == 0);
272   uint16_t cid = CreateConnection(kPsm, device_address);
273   ASSERT(cid != 0);
274 
275   WaitConnectionFuture();
276   ASSERT(NumberOfConnections() == 1);
277 
278   shim_l2cap_->CloseConnection(cid);
279 }
280 
TEST_F(ShimL2capTest,MaxCreatedConnections)281 TEST_F(ShimL2capTest, MaxCreatedConnections) {
282   for (int i = 0; i < 65536 - 64; i++) {
283     SetConnectionFuture();
284     uint16_t cid = CreateConnection(kPsm, device_address);
285     ASSERT(cid != 0);
286     WaitConnectionFuture();
287 
288     ASSERT(NumberOfConnections() == i + 1);
289   }
290   uint16_t cid = CreateConnection(kPsm, device_address);
291   ASSERT(cid == 0);
292 
293   ASSERT(NumberOfConnections() == 65536 - 64);
294 }
295 
TEST_F(ShimL2capTest,TwoDifferentCreatedConnections)296 TEST_F(ShimL2capTest, TwoDifferentCreatedConnections) {
297   {
298     SetConnectionFuture();
299     uint16_t cid = CreateConnection(kPsm, device_address);
300     ASSERT(cid != 0);
301     WaitConnectionFuture();
302 
303     ASSERT(NumberOfConnections() == 1);
304   }
305 
306   {
307     SetConnectionFuture();
308     uint16_t cid = CreateConnection(kPsm2, device_address2);
309     ASSERT(cid != 0);
310     WaitConnectionFuture();
311 
312     ASSERT(NumberOfConnections() == 2);
313   }
314 }
315 
TEST_F(ShimL2capTest,ConnectFail)316 TEST_F(ShimL2capTest, ConnectFail) {
317   SetConnectionFuture();
318   uint16_t cid = CreateConnection(kPsm, device_address);
319   ASSERT(cid != 0);
320   WaitConnectionFuture();
321 
322   ASSERT(NumberOfConnections() == 1);
323 
324   l2cap::classic::DynamicChannelManager::ConnectionResult result{
325       .connection_result_code = TestDynamicChannelManager::ConnectionResultCode::FAIL_NO_SERVICE_REGISTERED,
326       .hci_error = hci::ErrorCode::SUCCESS,
327       .l2cap_connection_response_result = l2cap::ConnectionResponseResult::SUCCESS,
328   };
329 
330   std::promise<void> on_fail_promise;
331   auto on_fail_future = on_fail_promise.get_future();
332   handler_->Post(common::BindOnce(&TestDynamicChannelManagerImpl::SetConnectionOnFail,
333                                   common::Unretained(test_l2cap_classic_module_->impl_.get()), result,
334                                   std::move(on_fail_promise)));
335   on_fail_future.wait();
336 
337   ASSERT(connection_connected_ == false);
338 
339   shim_l2cap_->CloseConnection(cid);
340 }
341 
TEST_F(ShimL2capTest,ConnectOpen)342 TEST_F(ShimL2capTest, ConnectOpen) {
343   SetConnectionFuture();
344   uint16_t cid = CreateConnection(kPsm, device_address);
345   ASSERT(cid != 0);
346   WaitConnectionFuture();
347 
348   ASSERT(NumberOfConnections() == 1);
349 
350   hci::Address address;
351   hci::Address::FromString(device_address, address);
352   test_link_.device_with_type_ = hci::AddressWithType(address, hci::AddressType::PUBLIC_DEVICE_ADDRESS);
353 
354   l2cap::Psm psm = kPsm;
355   l2cap::Cid local_cid = kCid;
356   l2cap::Cid remote_cid = kCid2;
357 
358   std::shared_ptr<l2cap::internal::DynamicChannelImpl> impl =
359       std::make_shared<l2cap::internal::DynamicChannelImpl>(psm, local_cid, remote_cid, &test_link_, handler_);
360 
361   auto channel = std::make_unique<l2cap::DynamicChannel>(impl, handler_);
362 
363   std::promise<void> on_fail_promise;
364   auto on_fail_future = on_fail_promise.get_future();
365 
366   auto connection_complete_future = connection_complete_promise_.get_future();
367   handler_->Post(common::BindOnce(&TestDynamicChannelManagerImpl::SetConnectionOnOpen,
368                                   common::Unretained(test_l2cap_classic_module_->impl_.get()), std::move(channel),
369                                   std::move(on_fail_promise)));
370   connection_complete_future.wait();
371 
372   on_fail_future.wait();
373 
374   ASSERT(connection_connected_ == true);
375 
376   auto future = test_link_.connection_closed_promise_.get_future();
377   shim_l2cap_->CloseConnection(cid);
378   future.wait();
379 }
380 
TEST_F(ShimL2capTest,RegisterService_Success)381 TEST_F(ShimL2capTest, RegisterService_Success) {
382   std::promise<uint16_t> registration_promise;
383   auto registration_pending = registration_promise.get_future();
384 
385   SetRegistrationFuture();
386   shim_l2cap_->RegisterService(
387       kPsm, kNoUseErtm, kMtu,
388       std::bind(&bluetooth::shim::ShimL2capTest::OnConnectionComplete, this, std::placeholders::_1,
389                 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
390       std::move(registration_promise));
391   WaitRegistrationFuture();
392   ASSERT_LOG(test_l2cap_classic_module_->impl_->on_registration_complete_, "Synchronization failure");
393   ASSERT(test_l2cap_classic_module_->impl_->services_ == 1);
394 
395   l2cap::classic::DynamicChannelManager::RegistrationResult result{
396       l2cap::classic::DynamicChannelManager::RegistrationResult::SUCCESS,
397   };
398   auto service = std::make_unique<TestDynamicChannelService>(kPsm, &mock_, handler_);
399 
400   handler_->Post(common::BindOnce(std::move(test_l2cap_classic_module_->impl_->on_registration_complete_), result,
401                                   std::move(service)));
402   uint16_t psm = registration_pending.get();
403   ASSERT(psm == kPsm);
404 }
405 
TEST_F(ShimL2capTest,RegisterService_Duplicate)406 TEST_F(ShimL2capTest, RegisterService_Duplicate) {
407   std::promise<uint16_t> promise;
408   auto future = promise.get_future();
409 
410   SetRegistrationFuture();
411   shim_l2cap_->RegisterService(
412       kPsm, kNoUseErtm, kMtu,
413       std::bind(&bluetooth::shim::ShimL2capTest::OnConnectionComplete, this, std::placeholders::_1,
414                 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
415       std::move(promise));
416   WaitRegistrationFuture();
417   ASSERT_LOG(test_l2cap_classic_module_->impl_->on_registration_complete_, "Synchronization failure");
418   ASSERT(test_l2cap_classic_module_->impl_->services_ == 1);
419 
420   l2cap::classic::DynamicChannelManager::RegistrationResult result{
421       l2cap::classic::DynamicChannelManager::RegistrationResult::FAIL_DUPLICATE_SERVICE,
422   };
423   auto service = std::make_unique<TestDynamicChannelService>(kPsm, &mock_, handler_);
424 
425   handler_->Post(common::BindOnce(std::move(test_l2cap_classic_module_->impl_->on_registration_complete_), result,
426                                   std::move(service)));
427   uint16_t psm = future.get();
428   ASSERT(psm == l2cap::kDefaultPsm);
429 }
430 
TEST_F(ShimL2capTest,RegisterService_Invalid)431 TEST_F(ShimL2capTest, RegisterService_Invalid) {
432   std::promise<uint16_t> promise;
433   auto future = promise.get_future();
434 
435   SetRegistrationFuture();
436 
437   shim_l2cap_->RegisterService(
438       kPsm, kNoUseErtm, kMtu,
439       std::bind(&bluetooth::shim::ShimL2capTest::OnConnectionComplete, this, std::placeholders::_1,
440                 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
441       std::move(promise));
442 
443   l2cap::classic::DynamicChannelManager::RegistrationResult result{
444       l2cap::classic::DynamicChannelManager::RegistrationResult::FAIL_INVALID_SERVICE,
445   };
446   auto service = std::make_unique<TestDynamicChannelService>(kPsm, &mock_, handler_);
447   WaitRegistrationFuture();
448 
449   ASSERT_LOG(test_l2cap_classic_module_->impl_->on_registration_complete_, "Synchronization failure");
450   handler_->Post(common::BindOnce(std::move(test_l2cap_classic_module_->impl_->on_registration_complete_), result,
451                                   std::move(service)));
452   uint16_t psm = future.get();
453   ASSERT(psm == l2cap::kDefaultPsm);
454   ASSERT(test_l2cap_classic_module_->impl_->services_ == 1);
455 }
456 
457 }  // namespace
458 }  // namespace shim
459 }  // namespace bluetooth
460