blob: 20eb155ca1bcc28d9904c014aa04705f2ab0167a [file] [log] [blame]
Chris Mantonee8c0a92019-10-17 10:56:37 -07001/*
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_shim"
17
18#include <functional>
19#include <memory>
20
21#include "common/bidi_queue.h"
22#include "hci/address.h"
23#include "hci/controller.h"
24#include "hci/hci_packets.h"
25#include "module.h"
26#include "neighbor/inquiry.h"
27#include "neighbor/scan_parameters.h"
28#include "os/handler.h"
29#include "os/log.h"
30#include "shim/inquiry.h"
31
32namespace bluetooth {
33namespace shim {
34
35struct Inquiry::impl {
36 void Result(hci::InquiryResultView view);
37 void ResultWithRssi(hci::InquiryResultWithRssiView view);
38 void ExtendedResult(hci::ExtendedInquiryResultView view);
39 void Complete(hci::ErrorCode status);
40
41 void RegisterInquiryResult(InquiryResultCallback callback);
42 void UnregisterInquiryResult();
43 void RegisterInquiryResultWithRssi(InquiryResultWithRssiCallback callback);
44 void UnregisterInquiryResultWithRssi();
45 void RegisterExtendedInquiryResult(ExtendedInquiryResultCallback callback);
46 void UnregisterExtendedInquiryResult();
47 void RegisterInquiryComplete(InquiryCompleteCallback callback);
48 void UnregisterInquiryComplete();
49 void RegisterInquiryCancelComplete(InquiryCancelCompleteCallback callback);
50 void UnregisterInquiryCancelComplete();
51
52 InquiryResultCallback shim_result_callback_;
53 InquiryResultWithRssiCallback shim_result_with_rssi_callback_;
54 ExtendedInquiryResultCallback shim_extended_result_callback_;
55 InquiryCompleteCallback shim_complete_callback_;
56 InquiryCancelCompleteCallback shim_cancel_complete_callback_;
57
58 neighbor::InquiryModule* module_{nullptr};
59
60 impl(neighbor::InquiryModule* module);
61 ~impl();
Myles Watsonca61a682019-12-02 17:39:03 -080062
63 neighbor::ScanParameters params_{
64 .interval = static_cast<neighbor::ScanInterval>(0),
65 .window = static_cast<neighbor::ScanWindow>(0),
66 };
67 bool general_inquiry_active_{false};
68 bool limited_inquiry_active_{false};
69 bool general_periodic_inquiry_active_{false};
70 bool limited_periodic_inquiry_active_{false};
Chris Mantonee8c0a92019-10-17 10:56:37 -070071};
72
73const ModuleFactory Inquiry::Factory = ModuleFactory([]() { return new Inquiry(); });
74
75void Inquiry::impl::Result(hci::InquiryResultView view) {
76 ASSERT(view.size() >= sizeof(uint16_t));
77 ASSERT(shim_result_callback_ != nullptr);
78 std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end());
79 shim_result_callback_(v);
80}
81
82void Inquiry::impl::ResultWithRssi(hci::InquiryResultWithRssiView view) {
83 ASSERT(view.size() >= sizeof(uint16_t));
84 ASSERT(shim_result_with_rssi_callback_ != nullptr);
85 std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end());
86 shim_result_with_rssi_callback_(v);
87}
88
89void Inquiry::impl::ExtendedResult(hci::ExtendedInquiryResultView view) {
90 ASSERT(view.size() >= sizeof(uint16_t));
91 ASSERT(shim_extended_result_callback_ != nullptr);
92 std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end());
93 shim_extended_result_callback_(v);
94}
95
96void Inquiry::impl::Complete(hci::ErrorCode status) {
97 ASSERT(shim_complete_callback_ != nullptr);
98 shim_complete_callback_(static_cast<uint16_t>(status));
99}
100
101void Inquiry::impl::RegisterInquiryResult(shim::InquiryResultCallback callback) {
102 if (shim_result_callback_ != nullptr) {
103 LOG_WARN("Registering inquiry result without unregistering");
104 }
105 shim_result_callback_ = callback;
106}
107
108void Inquiry::impl::UnregisterInquiryResult() {
109 if (shim_result_callback_ == nullptr) {
110 LOG_WARN("Unregistering inquiry result without registering");
111 }
112 shim_result_callback_ = nullptr;
113}
114
115void Inquiry::impl::RegisterInquiryResultWithRssi(shim::InquiryResultWithRssiCallback callback) {
116 if (shim_result_with_rssi_callback_ != nullptr) {
117 LOG_WARN("Registering inquiry result with rssi without unregistering");
118 }
119 shim_result_with_rssi_callback_ = callback;
120}
121
122void Inquiry::impl::UnregisterInquiryResultWithRssi() {
123 if (shim_result_with_rssi_callback_ == nullptr) {
124 LOG_WARN("Unregistering inquiry result with rssi without registering");
125 }
126 shim_result_with_rssi_callback_ = nullptr;
127}
128
129void Inquiry::impl::RegisterExtendedInquiryResult(shim::ExtendedInquiryResultCallback callback) {
130 if (shim_result_with_rssi_callback_ != nullptr) {
131 LOG_WARN("Registering extended inquiry result without unregistering");
132 }
133 shim_extended_result_callback_ = callback;
134}
135
136void Inquiry::impl::UnregisterExtendedInquiryResult() {
137 if (shim_extended_result_callback_ == nullptr) {
138 LOG_WARN("Unregistering extended inquiry result without registering");
139 }
140 shim_extended_result_callback_ = nullptr;
141}
142
143void Inquiry::impl::RegisterInquiryComplete(shim::InquiryCompleteCallback callback) {
144 if (shim_result_with_rssi_callback_ != nullptr) {
145 LOG_WARN("Registering inquiry complete without unregistering");
146 }
147 shim_complete_callback_ = callback;
148}
149
150void Inquiry::impl::UnregisterInquiryComplete() {
151 if (shim_result_with_rssi_callback_ == nullptr) {
152 LOG_WARN("Unregistering inquiry complete without registering");
153 }
154 shim_complete_callback_ = nullptr;
155}
156
157void Inquiry::impl::RegisterInquiryCancelComplete(shim::InquiryCancelCompleteCallback callback) {
158 if (shim_cancel_complete_callback_ != nullptr) {
159 LOG_WARN("Registering inquiry cancel complete without unregistering");
160 }
161 shim_cancel_complete_callback_ = callback;
162}
163
164void Inquiry::impl::UnregisterInquiryCancelComplete() {
165 if (shim_cancel_complete_callback_ == nullptr) {
166 LOG_WARN("Unregistering inquiry cancel complete without registering");
167 }
168 shim_cancel_complete_callback_ = nullptr;
169}
170
171Inquiry::impl::impl(neighbor::InquiryModule* inquiry_module) : module_(inquiry_module) {
172 neighbor::InquiryCallbacks inquiry_callbacks;
173 inquiry_callbacks.result = std::bind(&Inquiry::impl::Result, this, std::placeholders::_1);
174 inquiry_callbacks.result_with_rssi = std::bind(&Inquiry::impl::ResultWithRssi, this, std::placeholders::_1);
175 inquiry_callbacks.extended_result = std::bind(&Inquiry::impl::ExtendedResult, this, std::placeholders::_1);
176 inquiry_callbacks.complete = std::bind(&Inquiry::impl::Complete, this, std::placeholders::_1);
177
178 module_->RegisterCallbacks(inquiry_callbacks);
179}
180
181Inquiry::impl::~impl() {
182 module_->UnregisterCallbacks();
183}
184
185void Inquiry::StartGeneralInquiry(uint8_t inquiry_length, uint8_t num_responses) {
Myles Watsonca61a682019-12-02 17:39:03 -0800186 pimpl_->general_inquiry_active_ = true;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700187 return pimpl_->module_->StartGeneralInquiry(inquiry_length, num_responses);
188}
189
190void Inquiry::StartLimitedInquiry(uint8_t inquiry_length, uint8_t num_responses) {
Myles Watsonca61a682019-12-02 17:39:03 -0800191 pimpl_->limited_inquiry_active_ = true;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700192 return pimpl_->module_->StartLimitedInquiry(inquiry_length, num_responses);
193}
194
195void Inquiry::StopInquiry() {
Myles Watsonca61a682019-12-02 17:39:03 -0800196 pimpl_->limited_inquiry_active_ = false;
197 pimpl_->general_inquiry_active_ = false;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700198 return pimpl_->module_->StopInquiry();
199}
200
201bool Inquiry::IsGeneralInquiryActive() const {
Myles Watsonca61a682019-12-02 17:39:03 -0800202 return pimpl_->general_inquiry_active_;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700203}
204
205bool Inquiry::IsLimitedInquiryActive() const {
Myles Watsonca61a682019-12-02 17:39:03 -0800206 return pimpl_->limited_inquiry_active_;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700207}
208
209void Inquiry::StartGeneralPeriodicInquiry(uint8_t inquiry_length, uint8_t num_responses, uint16_t max_delay,
210 uint16_t min_delay) {
Myles Watsonca61a682019-12-02 17:39:03 -0800211 pimpl_->general_periodic_inquiry_active_ = true;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700212 return pimpl_->module_->StartGeneralPeriodicInquiry(inquiry_length, num_responses, max_delay, min_delay);
213}
214
215void Inquiry::StartLimitedPeriodicInquiry(uint8_t inquiry_length, uint8_t num_responses, uint16_t max_delay,
216 uint16_t min_delay) {
Myles Watsonca61a682019-12-02 17:39:03 -0800217 pimpl_->limited_periodic_inquiry_active_ = true;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700218 return pimpl_->module_->StartLimitedPeriodicInquiry(inquiry_length, num_responses, max_delay, min_delay);
219}
220
221void Inquiry::StopPeriodicInquiry() {
Myles Watsonca61a682019-12-02 17:39:03 -0800222 pimpl_->limited_periodic_inquiry_active_ = false;
223 pimpl_->general_periodic_inquiry_active_ = false;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700224 return pimpl_->module_->StopPeriodicInquiry();
225}
226
227bool Inquiry::IsGeneralPeriodicInquiryActive() const {
Myles Watsonca61a682019-12-02 17:39:03 -0800228 return pimpl_->general_periodic_inquiry_active_;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700229}
230
231bool Inquiry::IsLimitedPeriodicInquiryActive() const {
Myles Watsonca61a682019-12-02 17:39:03 -0800232 return pimpl_->limited_periodic_inquiry_active_;
Chris Mantonee8c0a92019-10-17 10:56:37 -0700233}
234
235void Inquiry::SetInterlacedScan() {
236 pimpl_->module_->SetInterlacedScan();
237}
238
239void Inquiry::SetStandardScan() {
240 pimpl_->module_->SetStandardScan();
241}
242
243void Inquiry::SetScanActivity(uint16_t interval, uint16_t window) {
Myles Watsonca61a682019-12-02 17:39:03 -0800244 pimpl_->params_.interval = interval;
245 pimpl_->params_.window = window;
246 pimpl_->module_->SetScanActivity(pimpl_->params_);
Chris Mantonee8c0a92019-10-17 10:56:37 -0700247}
248
249void Inquiry::GetScanActivity(uint16_t& interval, uint16_t& window) const {
Myles Watsonca61a682019-12-02 17:39:03 -0800250 interval = static_cast<uint16_t>(pimpl_->params_.interval);
251 window = static_cast<uint16_t>(pimpl_->params_.window);
Chris Mantonee8c0a92019-10-17 10:56:37 -0700252}
253
254void Inquiry::SetStandardInquiryResultMode() {
255 pimpl_->module_->SetStandardInquiryResultMode();
256}
257
258void Inquiry::SetInquiryWithRssiResultMode() {
259 pimpl_->module_->SetInquiryWithRssiResultMode();
260}
261
262void Inquiry::SetExtendedInquiryResultMode() {
263 pimpl_->module_->SetExtendedInquiryResultMode();
264}
265
266void Inquiry::RegisterInquiryResult(shim::InquiryResultCallback callback) {
267 pimpl_->RegisterInquiryResult(callback);
268}
269
270void Inquiry::UnregisterInquiryResult() {
271 pimpl_->UnregisterInquiryResult();
272}
273
274void Inquiry::RegisterInquiryResultWithRssi(shim::InquiryResultWithRssiCallback callback) {
275 pimpl_->RegisterInquiryResultWithRssi(callback);
276}
277
278void Inquiry::UnregisterInquiryResultWithRssi() {
279 pimpl_->UnregisterInquiryResultWithRssi();
280}
281
282void Inquiry::RegisterExtendedInquiryResult(shim::ExtendedInquiryResultCallback callback) {
283 pimpl_->RegisterExtendedInquiryResult(callback);
284}
285
286void Inquiry::UnregisterExtendedInquiryResult() {
287 pimpl_->UnregisterExtendedInquiryResult();
288}
289
290void Inquiry::RegisterInquiryComplete(InquiryCompleteCallback callback) {
291 pimpl_->RegisterInquiryComplete(callback);
292}
293
294void Inquiry::UnregisterInquiryComplete() {
295 pimpl_->UnregisterInquiryComplete();
296}
297
298void Inquiry::RegisterInquiryCancelComplete(InquiryCancelCompleteCallback callback) {
299 pimpl_->RegisterInquiryCancelComplete(callback);
300}
301
302void Inquiry::UnregisterInquiryCancelComplete() {
303 pimpl_->UnregisterInquiryCancelComplete();
304}
305
306/**
307 * Module methods
308 */
309void Inquiry::ListDependencies(ModuleList* list) {
310 list->add<neighbor::InquiryModule>();
311}
312
313void Inquiry::Start() {
314 pimpl_ = std::make_unique<impl>(GetDependency<neighbor::InquiryModule>());
315}
316
317void Inquiry::Stop() {
318 pimpl_.reset();
319}
320
321} // namespace shim
322} // namespace bluetooth