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