1 /* 2 * Copyright 2019 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 #include <memory> 17 #include <mutex> 18 #include <set> 19 20 #include "hci/controller.h" 21 #include "hci/hci_layer.h" 22 #include "hci/hci_packets.h" 23 #include "hci/le_scanning_interface.h" 24 #include "hci/le_scanning_manager.h" 25 #include "module.h" 26 #include "os/handler.h" 27 #include "os/log.h" 28 29 namespace bluetooth { 30 namespace hci { 31 32 constexpr uint16_t kDefaultLeScanWindow = 4800; 33 constexpr uint16_t kDefaultLeScanInterval = 4800; 34 35 const ModuleFactory LeScanningManager::Factory = ModuleFactory([]() { return new LeScanningManager(); }); 36 37 enum class ScanApiType { 38 LE_4_0 = 1, 39 ANDROID_HCI = 2, 40 LE_5_0 = 3, 41 }; 42 43 struct LeScanningManager::impl { 44 impl(Module* module) : module_(module), le_scanning_interface_(nullptr) {} 45 46 void start(os::Handler* handler, hci::HciLayer* hci_layer, hci::Controller* controller) { 47 module_handler_ = handler; 48 hci_layer_ = hci_layer; 49 controller_ = controller; 50 le_scanning_interface_ = hci_layer_->GetLeScanningInterface( 51 common::Bind(&LeScanningManager::impl::handle_scan_results, common::Unretained(this)), module_handler_); 52 if (controller_->IsSupported(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS)) { 53 api_type_ = ScanApiType::LE_5_0; 54 } else if (controller_->IsSupported(OpCode::LE_EXTENDED_SCAN_PARAMS)) { 55 api_type_ = ScanApiType::ANDROID_HCI; 56 } else { 57 api_type_ = ScanApiType::LE_4_0; 58 } 59 configure_scan(); 60 } 61 62 void handle_scan_results(LeMetaEventView event) { 63 switch (event.GetSubeventCode()) { 64 case hci::SubeventCode::ADVERTISING_REPORT: 65 handle_advertising_report<LeAdvertisingReportView, LeAdvertisingReport, LeReport>( 66 LeAdvertisingReportView::Create(event)); 67 break; 68 case hci::SubeventCode::DIRECTED_ADVERTISING_REPORT: 69 handle_advertising_report<LeDirectedAdvertisingReportView, LeDirectedAdvertisingReport, DirectedLeReport>( 70 LeDirectedAdvertisingReportView::Create(event)); 71 break; 72 case hci::SubeventCode::EXTENDED_ADVERTISING_REPORT: 73 handle_advertising_report<LeExtendedAdvertisingReportView, LeExtendedAdvertisingReport, ExtendedLeReport>( 74 LeExtendedAdvertisingReportView::Create(event)); 75 break; 76 case hci::SubeventCode::SCAN_TIMEOUT: 77 if (registered_callback_ != nullptr) { 78 registered_callback_->Handler()->Post( 79 common::BindOnce(&LeScanningManagerCallbacks::on_timeout, common::Unretained(registered_callback_))); 80 registered_callback_ = nullptr; 81 } 82 break; 83 default: 84 LOG_ALWAYS_FATAL("Unknown advertising subevent %s", hci::SubeventCodeText(event.GetSubeventCode()).c_str()); 85 } 86 } 87 88 template <class EventType, class ReportStructType, class ReportType> 89 void handle_advertising_report(EventType event_view) { 90 if (registered_callback_ == nullptr) { 91 LOG_INFO("Dropping advertising event (no registered handler)"); 92 return; 93 } 94 if (!event_view.IsValid()) { 95 LOG_INFO("Dropping invalid advertising event"); 96 return; 97 } 98 std::vector<ReportStructType> report_vector = event_view.GetAdvertisingReports(); 99 if (report_vector.empty()) { 100 LOG_INFO("Zero results in advertising event"); 101 return; 102 } 103 std::vector<std::shared_ptr<LeReport>> param; 104 param.reserve(report_vector.size()); 105 for (const ReportStructType& report : report_vector) { 106 param.push_back(std::shared_ptr<LeReport>(static_cast<LeReport*>(new ReportType(report)))); 107 } 108 registered_callback_->Handler()->Post(common::BindOnce(&LeScanningManagerCallbacks::on_advertisements, 109 common::Unretained(registered_callback_), param)); 110 } 111 112 void configure_scan() { 113 std::vector<PhyScanParameters> parameter_vector; 114 PhyScanParameters phy_scan_parameters; 115 phy_scan_parameters.le_scan_window_ = kDefaultLeScanWindow; 116 phy_scan_parameters.le_scan_interval_ = kDefaultLeScanInterval; 117 phy_scan_parameters.le_scan_type_ = LeScanType::ACTIVE; 118 parameter_vector.push_back(phy_scan_parameters); 119 uint8_t phys_in_use = 1; 120 121 switch (api_type_) { 122 case ScanApiType::LE_5_0: 123 le_scanning_interface_->EnqueueCommand(hci::LeSetExtendedScanParametersBuilder::Create( 124 own_address_type_, filter_policy_, phys_in_use, parameter_vector), 125 common::BindOnce(impl::check_status), module_handler_); 126 break; 127 case ScanApiType::ANDROID_HCI: 128 le_scanning_interface_->EnqueueCommand( 129 hci::LeExtendedScanParamsBuilder::Create(LeScanType::ACTIVE, interval_ms_, window_ms_, own_address_type_, 130 filter_policy_), 131 common::BindOnce(impl::check_status), module_handler_); 132 133 break; 134 case ScanApiType::LE_4_0: 135 le_scanning_interface_->EnqueueCommand( 136 hci::LeSetScanParametersBuilder::Create(LeScanType::ACTIVE, interval_ms_, window_ms_, own_address_type_, 137 filter_policy_), 138 common::BindOnce(impl::check_status), module_handler_); 139 break; 140 } 141 } 142 143 void start_scan(LeScanningManagerCallbacks* le_scanning_manager_callbacks) { 144 registered_callback_ = le_scanning_manager_callbacks; 145 switch (api_type_) { 146 case ScanApiType::LE_5_0: 147 le_scanning_interface_->EnqueueCommand( 148 hci::LeSetExtendedScanEnableBuilder::Create(Enable::ENABLED, 149 FilterDuplicates::DISABLED /* filter duplicates */, 0, 0), 150 common::BindOnce(impl::check_status), module_handler_); 151 break; 152 case ScanApiType::ANDROID_HCI: 153 case ScanApiType::LE_4_0: 154 le_scanning_interface_->EnqueueCommand( 155 hci::LeSetScanEnableBuilder::Create(Enable::ENABLED, Enable::DISABLED /* filter duplicates */), 156 common::BindOnce(impl::check_status), module_handler_); 157 break; 158 } 159 } 160 161 void stop_scan(common::Callback<void()> on_stopped) { 162 if (registered_callback_ == nullptr) { 163 return; 164 } 165 registered_callback_->Handler()->Post(std::move(on_stopped)); 166 switch (api_type_) { 167 case ScanApiType::LE_5_0: 168 le_scanning_interface_->EnqueueCommand( 169 hci::LeSetExtendedScanEnableBuilder::Create(Enable::DISABLED, 170 FilterDuplicates::DISABLED /* filter duplicates */, 0, 0), 171 common::BindOnce(impl::check_status), module_handler_); 172 registered_callback_ = nullptr; 173 break; 174 case ScanApiType::ANDROID_HCI: 175 case ScanApiType::LE_4_0: 176 le_scanning_interface_->EnqueueCommand( 177 hci::LeSetScanEnableBuilder::Create(Enable::DISABLED, Enable::DISABLED /* filter duplicates */), 178 common::BindOnce(impl::check_status), module_handler_); 179 registered_callback_ = nullptr; 180 break; 181 } 182 } 183 184 ScanApiType api_type_; 185 186 LeScanningManagerCallbacks* registered_callback_; 187 Module* module_; 188 os::Handler* module_handler_; 189 hci::HciLayer* hci_layer_; 190 hci::Controller* controller_; 191 hci::LeScanningInterface* le_scanning_interface_; 192 193 uint32_t interval_ms_{1000}; 194 uint16_t window_ms_{1000}; 195 AddressType own_address_type_{AddressType::PUBLIC_DEVICE_ADDRESS}; 196 LeSetScanningFilterPolicy filter_policy_{LeSetScanningFilterPolicy::ACCEPT_ALL}; 197 198 static void check_status(CommandCompleteView view) { 199 switch (view.GetCommandOpCode()) { 200 case (OpCode::LE_SET_SCAN_ENABLE): { 201 auto status_view = LeSetScanEnableCompleteView::Create(view); 202 ASSERT(status_view.IsValid()); 203 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS); 204 } break; 205 case (OpCode::LE_SET_EXTENDED_SCAN_ENABLE): { 206 auto status_view = LeSetExtendedScanEnableCompleteView::Create(view); 207 ASSERT(status_view.IsValid()); 208 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS); 209 } break; 210 case (OpCode::LE_SET_SCAN_PARAMETERS): { 211 auto status_view = LeSetScanParametersCompleteView::Create(view); 212 ASSERT(status_view.IsValid()); 213 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS); 214 } break; 215 case (OpCode::LE_EXTENDED_SCAN_PARAMS): { 216 auto status_view = LeExtendedScanParamsCompleteView::Create(view); 217 ASSERT(status_view.IsValid()); 218 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS); 219 } break; 220 case (OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS): { 221 auto status_view = LeSetExtendedScanParametersCompleteView::Create(view); 222 ASSERT(status_view.IsValid()); 223 ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS); 224 } break; 225 default: 226 LOG_ALWAYS_FATAL("Unhandled event %s", OpCodeText(view.GetCommandOpCode()).c_str()); 227 } 228 } 229 }; 230 231 LeScanningManager::LeScanningManager() { 232 pimpl_ = std::make_unique<impl>(this); 233 } 234 235 void LeScanningManager::ListDependencies(ModuleList* list) { 236 list->add<hci::HciLayer>(); 237 list->add<hci::Controller>(); 238 } 239 240 void LeScanningManager::Start() { 241 pimpl_->start(GetHandler(), GetDependency<hci::HciLayer>(), GetDependency<hci::Controller>()); 242 } 243 244 void LeScanningManager::Stop() { 245 pimpl_.reset(); 246 } 247 248 std::string LeScanningManager::ToString() const { 249 return "Le Scanning Manager"; 250 } 251 252 void LeScanningManager::StartScan(LeScanningManagerCallbacks* callbacks) { 253 GetHandler()->Post(common::Bind(&impl::start_scan, common::Unretained(pimpl_.get()), callbacks)); 254 } 255 256 void LeScanningManager::StopScan(common::Callback<void()> on_stopped) { 257 GetHandler()->Post(common::Bind(&impl::stop_scan, common::Unretained(pimpl_.get()), on_stopped)); 258 } 259 260 } // namespace hci 261 } // namespace bluetooth 262