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