• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "bt_gd_neigh"
17 
18 #include "neighbor/inquiry.h"
19 
20 #include <memory>
21 
22 #include "common/bind.h"
23 #include "hci/hci_layer.h"
24 #include "hci/hci_packets.h"
25 #include "module.h"
26 #include "os/handler.h"
27 #include "os/log.h"
28 
29 namespace bluetooth {
30 namespace neighbor {
31 
32 static constexpr uint8_t kGeneralInquiryAccessCode = 0x33;
33 static constexpr uint8_t kLimitedInquiryAccessCode = 0x00;
34 
35 struct InquiryModule::impl {
36   void RegisterCallbacks(InquiryCallbacks inquiry_callbacks);
37   void UnregisterCallbacks();
38 
39   void StartOneShotInquiry(bool limited, InquiryLength inquiry_length, NumResponses num_responses);
40   void StopOneShotInquiry();
41 
42   void StartPeriodicInquiry(bool limited, InquiryLength inquiry_length, NumResponses num_responses,
43                             PeriodLength max_delay, PeriodLength min_delay);
44   void StopPeriodicInquiry();
45 
46   void SetScanActivity(ScanParameters params);
47 
48   void SetScanType(hci::InquiryScanType scan_type);
49 
50   void SetInquiryMode(hci::InquiryMode mode);
51 
52   void Start();
53   void Stop();
54 
55   bool HasCallbacks() const;
56 
57   impl(InquiryModule& inquiry_module);
58 
59  private:
60   InquiryCallbacks inquiry_callbacks_;
61 
62   InquiryModule& module_;
63 
64   bool active_general_one_shot_{false};
65   bool active_limited_one_shot_{false};
66   bool active_general_periodic_{false};
67   bool active_limited_periodic_{false};
68 
69   ScanParameters inquiry_scan_;
70   hci::InquiryMode inquiry_mode_;
71   hci::InquiryScanType inquiry_scan_type_;
72   int8_t inquiry_response_tx_power_;
73 
74   bool IsInquiryActive() const;
75 
76   void EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command);
77   void EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command);
78   void OnCommandComplete(hci::CommandCompleteView view);
79   void OnCommandStatus(hci::CommandStatusView status);
80 
81   void EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command);
82   void OnCommandCompleteSync(hci::CommandCompleteView view);
83 
84   void OnEvent(hci::EventPacketView view);
85 
86   std::promise<void>* command_sync_{nullptr};
87 
88   hci::HciLayer* hci_layer_;
89   os::Handler* handler_;
90 };
91 
__anonde04eb3f0102() 92 const ModuleFactory neighbor::InquiryModule::Factory = ModuleFactory([]() { return new neighbor::InquiryModule(); });
93 
impl(neighbor::InquiryModule & module)94 neighbor::InquiryModule::impl::impl(neighbor::InquiryModule& module) : module_(module) {}
95 
OnCommandCompleteSync(hci::CommandCompleteView view)96 void neighbor::InquiryModule::impl::OnCommandCompleteSync(hci::CommandCompleteView view) {
97   OnCommandComplete(view);
98   ASSERT(command_sync_ != nullptr);
99   command_sync_->set_value();
100 }
101 
OnCommandComplete(hci::CommandCompleteView view)102 void neighbor::InquiryModule::impl::OnCommandComplete(hci::CommandCompleteView view) {
103   switch (view.GetCommandOpCode()) {
104     case hci::OpCode::INQUIRY_CANCEL: {
105       auto packet = hci::InquiryCancelCompleteView::Create(view);
106       ASSERT(packet.IsValid());
107       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
108     } break;
109 
110     case hci::OpCode::PERIODIC_INQUIRY_MODE: {
111       auto packet = hci::PeriodicInquiryModeCompleteView::Create(view);
112       ASSERT(packet.IsValid());
113       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
114     } break;
115 
116     case hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE: {
117       auto packet = hci::ExitPeriodicInquiryModeCompleteView::Create(view);
118       ASSERT(packet.IsValid());
119       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
120     } break;
121 
122     case hci::OpCode::WRITE_INQUIRY_MODE: {
123       auto packet = hci::WriteInquiryModeCompleteView::Create(view);
124       ASSERT(packet.IsValid());
125       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
126     } break;
127 
128     case hci::OpCode::READ_INQUIRY_MODE: {
129       auto packet = hci::ReadInquiryModeCompleteView::Create(view);
130       ASSERT(packet.IsValid());
131       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
132       inquiry_mode_ = packet.GetInquiryMode();
133     } break;
134 
135     case hci::OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL: {
136       auto packet = hci::ReadInquiryResponseTransmitPowerLevelCompleteView::Create(view);
137       ASSERT(packet.IsValid());
138       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
139       inquiry_response_tx_power_ = packet.GetTxPower();
140     } break;
141 
142     case hci::OpCode::WRITE_INQUIRY_SCAN_ACTIVITY: {
143       auto packet = hci::WriteInquiryScanActivityCompleteView::Create(view);
144       ASSERT(packet.IsValid());
145       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
146     } break;
147 
148     case hci::OpCode::READ_INQUIRY_SCAN_ACTIVITY: {
149       auto packet = hci::ReadInquiryScanActivityCompleteView::Create(view);
150       ASSERT(packet.IsValid());
151       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
152       inquiry_scan_.interval = packet.GetInquiryScanInterval();
153       inquiry_scan_.window = packet.GetInquiryScanWindow();
154     } break;
155 
156     case hci::OpCode::WRITE_INQUIRY_SCAN_TYPE: {
157       auto packet = hci::WriteInquiryScanTypeCompleteView::Create(view);
158       ASSERT(packet.IsValid());
159       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
160     } break;
161 
162     case hci::OpCode::READ_INQUIRY_SCAN_TYPE: {
163       auto packet = hci::ReadInquiryScanTypeCompleteView::Create(view);
164       ASSERT(packet.IsValid());
165       ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
166       inquiry_scan_type_ = packet.GetInquiryScanType();
167     } break;
168 
169     default:
170       LOG_WARN("Unhandled command:%s", hci::OpCodeText(view.GetCommandOpCode()).c_str());
171       break;
172   }
173 }
174 
OnCommandStatus(hci::CommandStatusView status)175 void neighbor::InquiryModule::impl::OnCommandStatus(hci::CommandStatusView status) {
176   ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS);
177 
178   switch (status.GetCommandOpCode()) {
179     case hci::OpCode::INQUIRY: {
180       auto packet = hci::InquiryStatusView::Create(status);
181       ASSERT(packet.IsValid());
182       if (active_limited_one_shot_ || active_general_one_shot_) {
183         LOG_DEBUG("Inquiry started lap: %s", active_limited_one_shot_ ? "Limited" : "General");
184       }
185     } break;
186 
187     default:
188       LOG_WARN("Unhandled command:%s", hci::OpCodeText(status.GetCommandOpCode()).c_str());
189       break;
190   }
191 }
192 
OnEvent(hci::EventPacketView view)193 void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) {
194   switch (view.GetEventCode()) {
195     case hci::EventCode::INQUIRY_COMPLETE: {
196       auto packet = hci::InquiryCompleteView::Create(view);
197       ASSERT(packet.IsValid());
198       LOG_DEBUG("inquiry complete");
199       active_limited_one_shot_ = false;
200       active_general_one_shot_ = false;
201       inquiry_callbacks_.complete(packet.GetStatus());
202     } break;
203 
204     case hci::EventCode::INQUIRY_RESULT: {
205       auto packet = hci::InquiryResultView::Create(view);
206       ASSERT(packet.IsValid());
207       LOG_DEBUG("Inquiry result size:%zd num_responses:%zu", packet.size(), packet.GetInquiryResults().size());
208       inquiry_callbacks_.result(packet);
209     } break;
210 
211     case hci::EventCode::INQUIRY_RESULT_WITH_RSSI: {
212       auto packet = hci::InquiryResultWithRssiView::Create(view);
213       ASSERT(packet.IsValid());
214       LOG_DEBUG("Inquiry result with rssi num_responses:%zu", packet.GetInquiryResults().size());
215       inquiry_callbacks_.result_with_rssi(packet);
216     } break;
217 
218     case hci::EventCode::EXTENDED_INQUIRY_RESULT: {
219       auto packet = hci::ExtendedInquiryResultView::Create(view);
220       ASSERT(packet.IsValid());
221       LOG_DEBUG("Extended inquiry result addr:%s repetition_mode:%s cod:%s clock_offset:%d rssi:%hhd",
222                 packet.GetAddress().ToString().c_str(),
223                 hci::PageScanRepetitionModeText(packet.GetPageScanRepetitionMode()).c_str(),
224                 packet.GetClassOfDevice().ToString().c_str(), packet.GetClockOffset(), packet.GetRssi());
225       inquiry_callbacks_.extended_result(packet);
226     } break;
227 
228     default:
229       LOG_ERROR("Unhandled event:%s", hci::EventCodeText(view.GetEventCode()).c_str());
230       break;
231   }
232 }
233 
234 /**
235  * impl
236  */
RegisterCallbacks(InquiryCallbacks callbacks)237 void neighbor::InquiryModule::impl::RegisterCallbacks(InquiryCallbacks callbacks) {
238   inquiry_callbacks_ = callbacks;
239 
240   hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT,
241                                    common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
242   hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI,
243                                    common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
244   hci_layer_->RegisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT,
245                                    common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
246   hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_COMPLETE,
247                                    common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
248 }
249 
UnregisterCallbacks()250 void neighbor::InquiryModule::impl::UnregisterCallbacks() {
251   hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_COMPLETE);
252   hci_layer_->UnregisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT);
253   hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI);
254   hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT);
255 
256   inquiry_callbacks_ = {nullptr, nullptr, nullptr, nullptr};
257 }
258 
EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command)259 void neighbor::InquiryModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command) {
260   hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)),
261                              handler_);
262 }
263 
EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command)264 void neighbor::InquiryModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command) {
265   hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)),
266                              handler_);
267 }
268 
EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command)269 void neighbor::InquiryModule::impl::EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command) {
270   ASSERT(command_sync_ == nullptr);
271   command_sync_ = new std::promise<void>();
272   auto command_received = command_sync_->get_future();
273   hci_layer_->EnqueueCommand(std::move(command),
274                              common::BindOnce(&impl::OnCommandCompleteSync, common::Unretained(this)), handler_);
275   command_received.wait();
276   delete command_sync_;
277   command_sync_ = nullptr;
278 }
279 
StartOneShotInquiry(bool limited,InquiryLength inquiry_length,NumResponses num_responses)280 void neighbor::InquiryModule::impl::StartOneShotInquiry(bool limited, InquiryLength inquiry_length,
281                                                         NumResponses num_responses) {
282   ASSERT(HasCallbacks());
283   ASSERT(!IsInquiryActive());
284   hci::Lap lap;
285   if (limited) {
286     active_limited_one_shot_ = true;
287     lap.lap_ = kLimitedInquiryAccessCode;
288   } else {
289     active_general_one_shot_ = true;
290     lap.lap_ = kGeneralInquiryAccessCode;
291   }
292   EnqueueCommandStatus(hci::InquiryBuilder::Create(lap, inquiry_length, num_responses));
293 }
294 
StopOneShotInquiry()295 void neighbor::InquiryModule::impl::StopOneShotInquiry() {
296   ASSERT(active_general_one_shot_ || active_limited_one_shot_);
297   active_general_one_shot_ = false;
298   active_limited_one_shot_ = false;
299   EnqueueCommandComplete(hci::InquiryCancelBuilder::Create());
300 }
301 
StartPeriodicInquiry(bool limited,InquiryLength inquiry_length,NumResponses num_responses,PeriodLength max_delay,PeriodLength min_delay)302 void neighbor::InquiryModule::impl::StartPeriodicInquiry(bool limited, InquiryLength inquiry_length,
303                                                          NumResponses num_responses, PeriodLength max_delay,
304                                                          PeriodLength min_delay) {
305   ASSERT(HasCallbacks());
306   ASSERT(!IsInquiryActive());
307   hci::Lap lap;
308   if (limited) {
309     active_limited_periodic_ = true;
310     lap.lap_ = kLimitedInquiryAccessCode;
311   } else {
312     active_general_periodic_ = true;
313     lap.lap_ = kGeneralInquiryAccessCode;
314   }
315   EnqueueCommandComplete(
316       hci::PeriodicInquiryModeBuilder::Create(max_delay, min_delay, lap, inquiry_length, num_responses));
317 }
318 
StopPeriodicInquiry()319 void neighbor::InquiryModule::impl::StopPeriodicInquiry() {
320   ASSERT(active_general_periodic_ || active_limited_periodic_);
321   active_general_periodic_ = false;
322   active_limited_periodic_ = false;
323   EnqueueCommandComplete(hci::ExitPeriodicInquiryModeBuilder::Create());
324 }
325 
IsInquiryActive() const326 bool neighbor::InquiryModule::impl::IsInquiryActive() const {
327   return active_general_one_shot_ || active_limited_one_shot_ || active_limited_periodic_ || active_general_periodic_;
328 }
329 
Start()330 void neighbor::InquiryModule::impl::Start() {
331   hci_layer_ = module_.GetDependency<hci::HciLayer>();
332   handler_ = module_.GetHandler();
333 
334   EnqueueCommandComplete(hci::ReadInquiryResponseTransmitPowerLevelBuilder::Create());
335   EnqueueCommandComplete(hci::ReadInquiryScanActivityBuilder::Create());
336   EnqueueCommandComplete(hci::ReadInquiryScanTypeBuilder::Create());
337   EnqueueCommandCompleteSync(hci::ReadInquiryModeBuilder::Create());
338 
339   LOG_DEBUG("Started inquiry module");
340 }
341 
Stop()342 void neighbor::InquiryModule::impl::Stop() {
343   LOG_INFO("Inquiry scan interval:%hu window:%hu", inquiry_scan_.interval, inquiry_scan_.window);
344   LOG_INFO("Inquiry mode:%s scan_type:%s", hci::InquiryModeText(inquiry_mode_).c_str(),
345            hci::InquiryScanTypeText(inquiry_scan_type_).c_str());
346   LOG_INFO("Inquiry response tx power:%hhd", inquiry_response_tx_power_);
347   LOG_DEBUG("Stopped inquiry module");
348 }
349 
SetInquiryMode(hci::InquiryMode mode)350 void neighbor::InquiryModule::impl::SetInquiryMode(hci::InquiryMode mode) {
351   EnqueueCommandComplete(hci::WriteInquiryModeBuilder::Create(mode));
352   inquiry_mode_ = mode;
353   LOG_DEBUG("Set inquiry mode:%s", hci::InquiryModeText(mode).c_str());
354 }
355 
SetScanActivity(ScanParameters params)356 void neighbor::InquiryModule::impl::SetScanActivity(ScanParameters params) {
357   EnqueueCommandComplete(hci::WriteInquiryScanActivityBuilder::Create(params.interval, params.window));
358   inquiry_scan_ = params;
359   LOG_DEBUG("Set scan activity interval:0x%x/%.02fms window:0x%x/%.02fms", params.interval,
360             ScanIntervalTimeMs(params.interval), params.window, ScanWindowTimeMs(params.window));
361 }
362 
SetScanType(hci::InquiryScanType scan_type)363 void neighbor::InquiryModule::impl::SetScanType(hci::InquiryScanType scan_type) {
364   EnqueueCommandComplete(hci::WriteInquiryScanTypeBuilder::Create(scan_type));
365   LOG_DEBUG("Set scan type:%s", hci::InquiryScanTypeText(scan_type).c_str());
366 }
367 
HasCallbacks() const368 bool neighbor::InquiryModule::impl::HasCallbacks() const {
369   return inquiry_callbacks_.result != nullptr && inquiry_callbacks_.result_with_rssi != nullptr &&
370          inquiry_callbacks_.extended_result != nullptr && inquiry_callbacks_.complete != nullptr;
371 }
372 
373 /**
374  * General API here
375  */
InquiryModule()376 neighbor::InquiryModule::InquiryModule() : pimpl_(std::make_unique<impl>(*this)) {}
377 
~InquiryModule()378 neighbor::InquiryModule::~InquiryModule() {
379   pimpl_.reset();
380 }
381 
RegisterCallbacks(InquiryCallbacks callbacks)382 void neighbor::InquiryModule::RegisterCallbacks(InquiryCallbacks callbacks) {
383   pimpl_->RegisterCallbacks(callbacks);
384 }
385 
UnregisterCallbacks()386 void neighbor::InquiryModule::UnregisterCallbacks() {
387   pimpl_->UnregisterCallbacks();
388 }
389 
StartGeneralInquiry(InquiryLength inquiry_length,NumResponses num_responses)390 void neighbor::InquiryModule::StartGeneralInquiry(InquiryLength inquiry_length, NumResponses num_responses) {
391   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::StartOneShotInquiry,
392                                       common::Unretained(pimpl_.get()), false, inquiry_length, num_responses));
393 }
394 
StartLimitedInquiry(InquiryLength inquiry_length,NumResponses num_responses)395 void neighbor::InquiryModule::StartLimitedInquiry(InquiryLength inquiry_length, NumResponses num_responses) {
396   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::StartOneShotInquiry,
397                                       common::Unretained(pimpl_.get()), true, inquiry_length, num_responses));
398 }
399 
StopInquiry()400 void neighbor::InquiryModule::StopInquiry() {
401   GetHandler()->Post(
402       common::BindOnce(&neighbor::InquiryModule::impl::StopOneShotInquiry, common::Unretained(pimpl_.get())));
403 }
404 
StartGeneralPeriodicInquiry(InquiryLength inquiry_length,NumResponses num_responses,PeriodLength max_delay,PeriodLength min_delay)405 void neighbor::InquiryModule::StartGeneralPeriodicInquiry(InquiryLength inquiry_length, NumResponses num_responses,
406                                                           PeriodLength max_delay, PeriodLength min_delay) {
407   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::StartPeriodicInquiry,
408                                       common::Unretained(pimpl_.get()), false, inquiry_length, num_responses, max_delay,
409                                       min_delay));
410 }
411 
StartLimitedPeriodicInquiry(InquiryLength inquiry_length,NumResponses num_responses,PeriodLength max_delay,PeriodLength min_delay)412 void neighbor::InquiryModule::StartLimitedPeriodicInquiry(InquiryLength inquiry_length, NumResponses num_responses,
413                                                           PeriodLength max_delay, PeriodLength min_delay) {
414   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::StartPeriodicInquiry,
415                                       common::Unretained(pimpl_.get()), true, inquiry_length, num_responses, max_delay,
416                                       min_delay));
417 }
418 
StopPeriodicInquiry()419 void neighbor::InquiryModule::StopPeriodicInquiry() {
420   GetHandler()->Post(
421       common::BindOnce(&neighbor::InquiryModule::impl::StopPeriodicInquiry, common::Unretained(pimpl_.get())));
422 }
423 
SetScanActivity(ScanParameters params)424 void neighbor::InquiryModule::SetScanActivity(ScanParameters params) {
425   GetHandler()->Post(
426       common::BindOnce(&neighbor::InquiryModule::impl::SetScanActivity, common::Unretained(pimpl_.get()), params));
427 }
428 
SetInterlacedScan()429 void neighbor::InquiryModule::SetInterlacedScan() {
430   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::SetScanType, common::Unretained(pimpl_.get()),
431                                       hci::InquiryScanType::INTERLACED));
432 }
433 
SetStandardScan()434 void neighbor::InquiryModule::SetStandardScan() {
435   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::SetScanType, common::Unretained(pimpl_.get()),
436                                       hci::InquiryScanType::STANDARD));
437 }
438 
SetStandardInquiryResultMode()439 void neighbor::InquiryModule::SetStandardInquiryResultMode() {
440   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::SetInquiryMode, common::Unretained(pimpl_.get()),
441                                       hci::InquiryMode::STANDARD));
442 }
443 
SetInquiryWithRssiResultMode()444 void neighbor::InquiryModule::SetInquiryWithRssiResultMode() {
445   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::SetInquiryMode, common::Unretained(pimpl_.get()),
446                                       hci::InquiryMode::RSSI));
447 }
448 
SetExtendedInquiryResultMode()449 void neighbor::InquiryModule::SetExtendedInquiryResultMode() {
450   GetHandler()->Post(common::BindOnce(&neighbor::InquiryModule::impl::SetInquiryMode, common::Unretained(pimpl_.get()),
451                                       hci::InquiryMode::RSSI_OR_EXTENDED));
452 }
453 
454 /**
455  * Module methods here
456  */
ListDependencies(ModuleList * list)457 void neighbor::InquiryModule::ListDependencies(ModuleList* list) {
458   list->add<hci::HciLayer>();
459 }
460 
Start()461 void neighbor::InquiryModule::Start() {
462   pimpl_->Start();
463 }
464 
Stop()465 void neighbor::InquiryModule::Stop() {
466   pimpl_->Stop();
467 }
468 
469 }  // namespace neighbor
470 }  // namespace bluetooth
471