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: 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: 57 hci::AddressWithType GetDevice() { 58 return device_with_type_; 59 } 60 hci::AddressWithType device_with_type_; 61 62 void SendLeCredit(l2cap::Cid local_cid, uint16_t credit) {} 63 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: 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 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 99 void SetConnectionFuture() { 100 connected_promise_ = std::promise<void>(); 101 } 102 103 void WaitConnectionFuture() { 104 connected_future_ = connected_promise_.get_future(); 105 connected_future_.wait(); 106 } 107 108 void SetRegistrationFuture() { 109 register_promise_ = std::promise<void>(); 110 } 111 112 void WaitRegistrationFuture() { 113 register_future_ = register_promise_.get_future(); 114 register_future_.wait(); 115 } 116 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 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: 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 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 } 160 TestDynamicChannelManager(TestDynamicChannelManagerImpl& impl) : impl_(impl) {} 161 TestDynamicChannelManagerImpl& impl_; 162 }; 163 164 class TestL2capClassicModule : public l2cap::classic::L2capClassicModule { 165 public: 166 std::unique_ptr<l2cap::classic::DynamicChannelManager> GetDynamicChannelManager() override { 167 ASSERT(impl_ != nullptr); 168 return std::make_unique<TestDynamicChannelManager>(*impl_); 169 } 170 171 void ListDependencies(ModuleList* list) override {} 172 void Start() override; 173 void Stop() override; 174 175 std::unique_ptr<TestDynamicChannelManagerImpl> impl_; 176 }; 177 178 void TestL2capClassicModule::Start() { 179 impl_ = std::make_unique<TestDynamicChannelManagerImpl>(); 180 } 181 182 void TestL2capClassicModule::Stop() { 183 impl_.reset(); 184 } 185 186 class ShimL2capTest : public ::testing::Test { 187 public: 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 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 208 void SetConnectionFuture() { 209 test_l2cap_classic_module_->impl_->SetConnectionFuture(); 210 } 211 212 void WaitConnectionFuture() { 213 test_l2cap_classic_module_->impl_->WaitConnectionFuture(); 214 } 215 216 void SetRegistrationFuture() { 217 test_l2cap_classic_module_->impl_->SetRegistrationFuture(); 218 } 219 220 void WaitRegistrationFuture() { 221 test_l2cap_classic_module_->impl_->WaitRegistrationFuture(); 222 } 223 224 int NumberOfConnections() const { 225 return test_l2cap_classic_module_->impl_->connections_; 226 } 227 228 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: 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 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 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 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 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 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 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 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 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 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