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