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
17 #define LOG_TAG "bt_shim_btm"
18
19 #include "main/shim/btm.h"
20
21 #include <base/logging.h>
22
23 #include <algorithm>
24 #include <chrono>
25 #include <cstddef>
26 #include <cstdint>
27 #include <cstring>
28 #include <mutex>
29
30 #include "bta/include/bta_api.h"
31 #include "gd/hci/le_advertising_manager.h"
32 #include "gd/hci/le_scanning_manager.h"
33 #include "gd/neighbor/connectability.h"
34 #include "gd/neighbor/discoverability.h"
35 #include "gd/neighbor/inquiry.h"
36 #include "gd/neighbor/page.h"
37 #include "gd/security/security_module.h"
38 #include "main/shim/controller.h"
39 #include "main/shim/entry.h"
40 #include "main/shim/helpers.h"
41 #include "main/shim/shim.h"
42 #include "stack/btm/btm_dev.h"
43 #include "stack/btm/btm_int_types.h"
44 #include "types/ble_address_with_type.h"
45 #include "types/bluetooth/uuid.h"
46 #include "types/bt_transport.h"
47 #include "types/raw_address.h"
48
49 extern tBTM_CB btm_cb;
50
51 static constexpr bool kActiveScanning = true;
52 static constexpr bool kPassiveScanning = false;
53
54 using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME;
55
56 void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode);
57 void btm_process_inq_complete(tHCI_STATUS status, uint8_t result_type);
58 void btm_ble_process_adv_addr(RawAddress& raw_address,
59 tBLE_ADDR_TYPE* address_type);
60 void btm_ble_process_adv_pkt_cont(uint16_t event_type,
61 tBLE_ADDR_TYPE address_type,
62 const RawAddress& raw_address,
63 uint8_t primary_phy, uint8_t secondary_phy,
64 uint8_t advertising_sid, int8_t tx_power,
65 int8_t rssi, uint16_t periodic_adv_int,
66 uint8_t data_len, const uint8_t* data,
67 const RawAddress& original_bda);
68
69 void btm_api_process_inquiry_result(const RawAddress& raw_address,
70 uint8_t page_scan_rep_mode,
71 DEV_CLASS device_class,
72 uint16_t clock_offset);
73
74 void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address,
75 uint8_t page_scan_rep_mode,
76 DEV_CLASS device_class,
77 uint16_t clock_offset,
78 int8_t rssi);
79
80 void btm_api_process_extended_inquiry_result(RawAddress raw_address,
81 uint8_t page_scan_rep_mode,
82 DEV_CLASS device_class,
83 uint16_t clock_offset, int8_t rssi,
84 const uint8_t* eir_data,
85 size_t eir_len);
86
87 namespace bluetooth {
88
89 namespace shim {
90
Start(RawAddress raw_address)91 bool Btm::ReadRemoteName::Start(RawAddress raw_address) {
92 std::unique_lock<std::mutex> lock(mutex_);
93 if (in_progress_) {
94 return false;
95 }
96 raw_address_ = raw_address;
97 in_progress_ = true;
98 return true;
99 }
100
Stop()101 void Btm::ReadRemoteName::Stop() {
102 std::unique_lock<std::mutex> lock(mutex_);
103 raw_address_ = RawAddress::kEmpty;
104 in_progress_ = false;
105 }
106
IsInProgress() const107 bool Btm::ReadRemoteName::IsInProgress() const { return in_progress_; }
AddressString() const108 std::string Btm::ReadRemoteName::AddressString() const {
109 return raw_address_.ToString();
110 }
111
OnScannerRegistered(const bluetooth::hci::Uuid app_uuid,bluetooth::hci::ScannerId scanner_id,ScanningStatus status)112 void Btm::ScanningCallbacks::OnScannerRegistered(
113 const bluetooth::hci::Uuid app_uuid, bluetooth::hci::ScannerId scanner_id,
114 ScanningStatus status){};
115
OnSetScannerParameterComplete(bluetooth::hci::ScannerId scanner_id,ScanningStatus status)116 void Btm::ScanningCallbacks::OnSetScannerParameterComplete(
117 bluetooth::hci::ScannerId scanner_id, ScanningStatus status){};
118
OnScanResult(uint16_t event_type,uint8_t address_type,bluetooth::hci::Address address,uint8_t primary_phy,uint8_t secondary_phy,uint8_t advertising_sid,int8_t tx_power,int8_t rssi,uint16_t periodic_advertising_interval,std::vector<uint8_t> advertising_data)119 void Btm::ScanningCallbacks::OnScanResult(
120 uint16_t event_type, uint8_t address_type, bluetooth::hci::Address address,
121 uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid,
122 int8_t tx_power, int8_t rssi, uint16_t periodic_advertising_interval,
123 std::vector<uint8_t> advertising_data) {
124 tBLE_ADDR_TYPE ble_address_type = to_ble_addr_type(address_type);
125 uint16_t extended_event_type = 0;
126
127 RawAddress raw_address;
128 RawAddress::FromString(address.ToString(), raw_address);
129
130 if (ble_address_type != BLE_ADDR_ANONYMOUS) {
131 btm_ble_process_adv_addr(raw_address, &ble_address_type);
132 }
133
134 // Pass up to GattService#onScanResult
135 RawAddress original_bda = raw_address;
136 btm_ble_process_adv_addr(raw_address, &ble_address_type);
137 btm_ble_process_adv_pkt_cont(
138 extended_event_type, ble_address_type, raw_address, primary_phy,
139 secondary_phy, advertising_sid, tx_power, rssi,
140 periodic_advertising_interval, advertising_data.size(),
141 &advertising_data[0], original_bda);
142 }
143
OnTrackAdvFoundLost(bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info)144 void Btm::ScanningCallbacks::OnTrackAdvFoundLost(
145 bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info){};
OnBatchScanReports(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)146 void Btm::ScanningCallbacks::OnBatchScanReports(int client_if, int status,
147 int report_format,
148 int num_records,
149 std::vector<uint8_t> data){};
150
OnBatchScanThresholdCrossed(int client_if)151 void Btm::ScanningCallbacks::OnBatchScanThresholdCrossed(int client_if){};
OnTimeout()152 void Btm::ScanningCallbacks::OnTimeout(){};
OnFilterEnable(bluetooth::hci::Enable enable,uint8_t status)153 void Btm::ScanningCallbacks::OnFilterEnable(bluetooth::hci::Enable enable,
154 uint8_t status){};
OnFilterParamSetup(uint8_t available_spaces,bluetooth::hci::ApcfAction action,uint8_t status)155 void Btm::ScanningCallbacks::OnFilterParamSetup(
156 uint8_t available_spaces, bluetooth::hci::ApcfAction action,
157 uint8_t status){};
OnFilterConfigCallback(bluetooth::hci::ApcfFilterType filter_type,uint8_t available_spaces,bluetooth::hci::ApcfAction action,uint8_t status)158 void Btm::ScanningCallbacks::OnFilterConfigCallback(
159 bluetooth::hci::ApcfFilterType filter_type, uint8_t available_spaces,
160 bluetooth::hci::ApcfAction action, uint8_t status){};
OnPeriodicSyncStarted(int reg_id,uint8_t status,uint16_t sync_handle,uint8_t advertising_sid,bluetooth::hci::AddressWithType address_with_type,uint8_t phy,uint16_t interval)161 void Btm::ScanningCallbacks::OnPeriodicSyncStarted(
162 int reg_id, uint8_t status, uint16_t sync_handle, uint8_t advertising_sid,
163 bluetooth::hci::AddressWithType address_with_type, uint8_t phy,
164 uint16_t interval) {}
OnPeriodicSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t status,std::vector<uint8_t> data)165 void Btm::ScanningCallbacks::OnPeriodicSyncReport(uint16_t sync_handle,
166 int8_t tx_power, int8_t rssi,
167 uint8_t status,
168 std::vector<uint8_t> data) {}
OnPeriodicSyncLost(uint16_t sync_handle)169 void Btm::ScanningCallbacks::OnPeriodicSyncLost(uint16_t sync_handle) {}
OnPeriodicSyncTransferred(int pa_source,uint8_t status,bluetooth::hci::Address address)170 void Btm::ScanningCallbacks::OnPeriodicSyncTransferred(
171 int pa_source, uint8_t status, bluetooth::hci::Address address) {}
OnBigInfoReport(uint16_t sync_handle,bool encrypted)172 void Btm::ScanningCallbacks::OnBigInfoReport(uint16_t sync_handle, bool encrypted) {}
173
Btm(os::Handler * handler,neighbor::InquiryModule * inquiry)174 Btm::Btm(os::Handler* handler, neighbor::InquiryModule* inquiry)
175 : scanning_timer_(handler), observing_timer_(handler) {
176 ASSERT(handler != nullptr);
177 ASSERT(inquiry != nullptr);
178 bluetooth::neighbor::InquiryCallbacks inquiry_callbacks = {
179 .result = std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1),
180 .result_with_rssi =
181 std::bind(&Btm::OnInquiryResultWithRssi, this, std::placeholders::_1),
182 .extended_result =
183 std::bind(&Btm::OnExtendedInquiryResult, this, std::placeholders::_1),
184 .complete =
185 std::bind(&Btm::OnInquiryComplete, this, std::placeholders::_1)};
186 inquiry->RegisterCallbacks(std::move(inquiry_callbacks));
187 }
188
OnInquiryResult(bluetooth::hci::InquiryResultView view)189 void Btm::OnInquiryResult(bluetooth::hci::InquiryResultView view) {
190 for (auto& response : view.GetResponses()) {
191 btm_api_process_inquiry_result(
192 ToRawAddress(response.bd_addr_),
193 static_cast<uint8_t>(response.page_scan_repetition_mode_),
194 response.class_of_device_.data(), response.clock_offset_);
195 }
196 }
197
OnInquiryResultWithRssi(bluetooth::hci::InquiryResultWithRssiView view)198 void Btm::OnInquiryResultWithRssi(
199 bluetooth::hci::InquiryResultWithRssiView view) {
200 for (auto& response : view.GetResponses()) {
201 btm_api_process_inquiry_result_with_rssi(
202 ToRawAddress(response.address_),
203 static_cast<uint8_t>(response.page_scan_repetition_mode_),
204 response.class_of_device_.data(), response.clock_offset_,
205 response.rssi_);
206 }
207 }
208
OnExtendedInquiryResult(bluetooth::hci::ExtendedInquiryResultView view)209 void Btm::OnExtendedInquiryResult(
210 bluetooth::hci::ExtendedInquiryResultView view) {
211 constexpr size_t kMaxExtendedInquiryResponse = 240;
212 uint8_t gap_data_buffer[kMaxExtendedInquiryResponse];
213 uint8_t* data = nullptr;
214 size_t data_len = 0;
215
216 if (!view.GetExtendedInquiryResponse().empty()) {
217 bzero(gap_data_buffer, sizeof(gap_data_buffer));
218 uint8_t* p = gap_data_buffer;
219 for (auto gap_data : view.GetExtendedInquiryResponse()) {
220 *p++ = gap_data.data_.size() + sizeof(gap_data.data_type_);
221 *p++ = static_cast<uint8_t>(gap_data.data_type_);
222 p = (uint8_t*)memcpy(p, &gap_data.data_[0], gap_data.data_.size()) +
223 gap_data.data_.size();
224 }
225 data = gap_data_buffer;
226 data_len = p - data;
227 }
228
229 btm_api_process_extended_inquiry_result(
230 ToRawAddress(view.GetAddress()),
231 static_cast<uint8_t>(view.GetPageScanRepetitionMode()),
232 view.GetClassOfDevice().data(), view.GetClockOffset(), view.GetRssi(),
233 data, data_len);
234 }
235
OnInquiryComplete(bluetooth::hci::ErrorCode status)236 void Btm::OnInquiryComplete(bluetooth::hci::ErrorCode status) {
237 limited_inquiry_active_ = false;
238 general_inquiry_active_ = false;
239 legacy_inquiry_complete_callback_((static_cast<uint16_t>(status) == 0)
240 ? (BTM_SUCCESS)
241 : (BTM_ERR_PROCESSING),
242 active_inquiry_mode_);
243
244 active_inquiry_mode_ = kInquiryModeOff;
245 }
246
SetStandardInquiryResultMode()247 void Btm::SetStandardInquiryResultMode() {
248 GetInquiry()->SetStandardInquiryResultMode();
249 }
250
SetInquiryWithRssiResultMode()251 void Btm::SetInquiryWithRssiResultMode() {
252 GetInquiry()->SetInquiryWithRssiResultMode();
253 }
254
SetExtendedInquiryResultMode()255 void Btm::SetExtendedInquiryResultMode() {
256 GetInquiry()->SetExtendedInquiryResultMode();
257 }
258
SetInterlacedInquiryScan()259 void Btm::SetInterlacedInquiryScan() { GetInquiry()->SetInterlacedScan(); }
260
SetStandardInquiryScan()261 void Btm::SetStandardInquiryScan() { GetInquiry()->SetStandardScan(); }
262
IsInterlacedScanSupported() const263 bool Btm::IsInterlacedScanSupported() const {
264 return controller_get_interface()->supports_interlaced_inquiry_scan();
265 }
266
267 /**
268 * One shot inquiry
269 */
StartInquiry(uint8_t mode,uint8_t duration,uint8_t max_responses,LegacyInquiryCompleteCallback legacy_inquiry_complete_callback)270 bool Btm::StartInquiry(
271 uint8_t mode, uint8_t duration, uint8_t max_responses,
272 LegacyInquiryCompleteCallback legacy_inquiry_complete_callback) {
273 switch (mode) {
274 case kInquiryModeOff:
275 LOG_INFO("%s Stopping inquiry mode", __func__);
276 if (limited_inquiry_active_ || general_inquiry_active_) {
277 GetInquiry()->StopInquiry();
278 limited_inquiry_active_ = false;
279 general_inquiry_active_ = false;
280 }
281 active_inquiry_mode_ = kInquiryModeOff;
282 break;
283
284 case kLimitedInquiryMode:
285 case kGeneralInquiryMode: {
286 if (mode == kLimitedInquiryMode) {
287 LOG_INFO(
288
289 "%s Starting limited inquiry mode duration:%hhd max responses:%hhd",
290 __func__, duration, max_responses);
291 limited_inquiry_active_ = true;
292 GetInquiry()->StartLimitedInquiry(duration, max_responses);
293 active_inquiry_mode_ = kLimitedInquiryMode;
294 } else {
295 LOG_INFO(
296
297 "%s Starting general inquiry mode duration:%hhd max responses:%hhd",
298 __func__, duration, max_responses);
299 general_inquiry_active_ = true;
300 GetInquiry()->StartGeneralInquiry(duration, max_responses);
301 legacy_inquiry_complete_callback_ = legacy_inquiry_complete_callback;
302 }
303 } break;
304
305 default:
306 LOG_WARN("%s Unknown inquiry mode:%d", __func__, mode);
307 return false;
308 }
309 return true;
310 }
311
CancelInquiry()312 void Btm::CancelInquiry() {
313 LOG_INFO("%s", __func__);
314 if (limited_inquiry_active_ || general_inquiry_active_) {
315 GetInquiry()->StopInquiry();
316 limited_inquiry_active_ = false;
317 general_inquiry_active_ = false;
318 }
319 }
320
IsInquiryActive() const321 bool Btm::IsInquiryActive() const {
322 return IsGeneralInquiryActive() || IsLimitedInquiryActive();
323 }
324
IsGeneralInquiryActive() const325 bool Btm::IsGeneralInquiryActive() const { return general_inquiry_active_; }
326
IsLimitedInquiryActive() const327 bool Btm::IsLimitedInquiryActive() const { return limited_inquiry_active_; }
328
329 /**
330 * Periodic
331 */
StartPeriodicInquiry(uint8_t mode,uint8_t duration,uint8_t max_responses,uint16_t max_delay,uint16_t min_delay,tBTM_INQ_RESULTS_CB * p_results_cb)332 bool Btm::StartPeriodicInquiry(uint8_t mode, uint8_t duration,
333 uint8_t max_responses, uint16_t max_delay,
334 uint16_t min_delay,
335 tBTM_INQ_RESULTS_CB* p_results_cb) {
336 switch (mode) {
337 case kInquiryModeOff:
338 limited_periodic_inquiry_active_ = false;
339 general_periodic_inquiry_active_ = false;
340 GetInquiry()->StopPeriodicInquiry();
341 break;
342
343 case kLimitedInquiryMode:
344 case kGeneralInquiryMode: {
345 if (mode == kLimitedInquiryMode) {
346 LOG_INFO("%s Starting limited periodic inquiry mode", __func__);
347 limited_periodic_inquiry_active_ = true;
348 GetInquiry()->StartLimitedPeriodicInquiry(duration, max_responses,
349 max_delay, min_delay);
350 } else {
351 LOG_INFO("%s Starting general periodic inquiry mode", __func__);
352 general_periodic_inquiry_active_ = true;
353 GetInquiry()->StartGeneralPeriodicInquiry(duration, max_responses,
354 max_delay, min_delay);
355 }
356 } break;
357
358 default:
359 LOG_WARN("%s Unknown inquiry mode:%d", __func__, mode);
360 return false;
361 }
362 return true;
363 }
364
IsGeneralPeriodicInquiryActive() const365 bool Btm::IsGeneralPeriodicInquiryActive() const {
366 return general_periodic_inquiry_active_;
367 }
368
IsLimitedPeriodicInquiryActive() const369 bool Btm::IsLimitedPeriodicInquiryActive() const {
370 return limited_periodic_inquiry_active_;
371 }
372
373 /**
374 * Discoverability
375 */
376
377 bluetooth::neighbor::ScanParameters params_{
378 .interval = 0,
379 .window = 0,
380 };
381
SetClassicGeneralDiscoverability(uint16_t window,uint16_t interval)382 void Btm::SetClassicGeneralDiscoverability(uint16_t window, uint16_t interval) {
383 params_.window = window;
384 params_.interval = interval;
385
386 GetInquiry()->SetScanActivity(params_);
387 GetDiscoverability()->StartGeneralDiscoverability();
388 }
389
SetClassicLimitedDiscoverability(uint16_t window,uint16_t interval)390 void Btm::SetClassicLimitedDiscoverability(uint16_t window, uint16_t interval) {
391 params_.window = window;
392 params_.interval = interval;
393 GetInquiry()->SetScanActivity(params_);
394 GetDiscoverability()->StartLimitedDiscoverability();
395 }
396
SetClassicDiscoverabilityOff()397 void Btm::SetClassicDiscoverabilityOff() {
398 GetDiscoverability()->StopDiscoverability();
399 }
400
GetClassicDiscoverabilityState() const401 DiscoverabilityState Btm::GetClassicDiscoverabilityState() const {
402 DiscoverabilityState state{.mode = BTM_NON_DISCOVERABLE,
403 .interval = params_.interval,
404 .window = params_.window};
405
406 if (GetDiscoverability()->IsGeneralDiscoverabilityEnabled()) {
407 state.mode = BTM_GENERAL_DISCOVERABLE;
408 } else if (GetDiscoverability()->IsLimitedDiscoverabilityEnabled()) {
409 state.mode = BTM_LIMITED_DISCOVERABLE;
410 }
411 return state;
412 }
413
SetLeGeneralDiscoverability()414 void Btm::SetLeGeneralDiscoverability() {
415 LOG_WARN("UNIMPLEMENTED %s", __func__);
416 }
417
SetLeLimitedDiscoverability()418 void Btm::SetLeLimitedDiscoverability() {
419 LOG_WARN("UNIMPLEMENTED %s", __func__);
420 }
421
SetLeDiscoverabilityOff()422 void Btm::SetLeDiscoverabilityOff() { LOG_WARN("UNIMPLEMENTED %s", __func__); }
423
GetLeDiscoverabilityState() const424 DiscoverabilityState Btm::GetLeDiscoverabilityState() const {
425 DiscoverabilityState state{
426 .mode = kDiscoverableModeOff,
427 .interval = 0,
428 .window = 0,
429 };
430 LOG_WARN("UNIMPLEMENTED %s", __func__);
431 return state;
432 }
433
434 /**
435 * Connectability
436 */
SetClassicConnectibleOn()437 void Btm::SetClassicConnectibleOn() {
438 GetConnectability()->StartConnectability();
439 }
440
SetClassicConnectibleOff()441 void Btm::SetClassicConnectibleOff() {
442 GetConnectability()->StopConnectability();
443 }
444
GetClassicConnectabilityState() const445 ConnectabilityState Btm::GetClassicConnectabilityState() const {
446 ConnectabilityState state{.interval = params_.interval,
447 .window = params_.window};
448
449 if (GetConnectability()->IsConnectable()) {
450 state.mode = BTM_CONNECTABLE;
451 } else {
452 state.mode = BTM_NON_CONNECTABLE;
453 }
454 return state;
455 }
456
SetInterlacedPageScan()457 void Btm::SetInterlacedPageScan() { GetPage()->SetInterlacedScan(); }
458
SetStandardPageScan()459 void Btm::SetStandardPageScan() { GetPage()->SetStandardScan(); }
460
SetLeConnectibleOn()461 void Btm::SetLeConnectibleOn() { LOG_WARN("UNIMPLEMENTED %s", __func__); }
462
SetLeConnectibleOff()463 void Btm::SetLeConnectibleOff() { LOG_WARN("UNIMPLEMENTED %s", __func__); }
464
GetLeConnectabilityState() const465 ConnectabilityState Btm::GetLeConnectabilityState() const {
466 ConnectabilityState state{
467 .mode = kConnectibleModeOff,
468 .interval = 0,
469 .window = 0,
470 };
471 LOG_WARN("UNIMPLEMENTED %s", __func__);
472 return state;
473 }
474
UseLeLink(const RawAddress & raw_address) const475 bool Btm::UseLeLink(const RawAddress& raw_address) const {
476 if (GetAclManager()->HACK_GetHandle(ToGdAddress(raw_address)) != 0xFFFF) {
477 return false;
478 }
479 if (GetAclManager()->HACK_GetLeHandle(ToGdAddress(raw_address)) != 0xFFFF) {
480 return true;
481 }
482 // TODO(hsz): use correct transport by using storage records. For now assume
483 // LE for GATT and HID.
484 return true;
485 }
486
ReadClassicRemoteDeviceName(const RawAddress & raw_address,tBTM_NAME_CMPL_CB * callback)487 BtmStatus Btm::ReadClassicRemoteDeviceName(const RawAddress& raw_address,
488 tBTM_NAME_CMPL_CB* callback) {
489 LOG_ALWAYS_FATAL("unreachable");
490 return BTM_UNDEFINED;
491 }
492
ReadLeRemoteDeviceName(const RawAddress & raw_address,tBTM_NAME_CMPL_CB * callback)493 BtmStatus Btm::ReadLeRemoteDeviceName(const RawAddress& raw_address,
494 tBTM_NAME_CMPL_CB* callback) {
495 if (!CheckLeAclLink(raw_address)) {
496 return BTM_UNKNOWN_ADDR;
497 }
498
499 if (!le_read_remote_name_.Start(raw_address)) {
500 return BTM_BUSY;
501 }
502
503 LOG_INFO("UNIMPLEMENTED %s need access to GATT module", __func__);
504 return BTM_UNKNOWN_ADDR;
505 }
506
CancelAllReadRemoteDeviceName()507 BtmStatus Btm::CancelAllReadRemoteDeviceName() {
508 LOG_ALWAYS_FATAL("unreachable");
509 return BTM_UNDEFINED;
510 }
511
StartAdvertising()512 void Btm::StartAdvertising() { LOG_ALWAYS_FATAL("unreachable"); }
513
StopAdvertising()514 void Btm::StopAdvertising() {
515 if (advertiser_id_ == hci::LeAdvertisingManager::kInvalidId) {
516 LOG_WARN("%s No active advertising", __func__);
517 return;
518 }
519 GetAdvertising()->RemoveAdvertiser(advertiser_id_);
520 advertiser_id_ = hci::LeAdvertisingManager::kInvalidId;
521 LOG_INFO("%s Stopped advertising", __func__);
522 }
523
StartConnectability()524 void Btm::StartConnectability() { StartAdvertising(); }
525
StopConnectability()526 void Btm::StopConnectability() { StopAdvertising(); }
527
StartActiveScanning()528 void Btm::StartActiveScanning() { StartScanning(kActiveScanning); }
529
StopActiveScanning()530 void Btm::StopActiveScanning() { GetScanning()->Scan(false); }
531
SetScanningTimer(uint64_t duration_ms,common::OnceCallback<void ()> callback)532 void Btm::SetScanningTimer(uint64_t duration_ms,
533 common::OnceCallback<void()> callback) {
534 scanning_timer_.Schedule(std::move(callback),
535 std::chrono::milliseconds(duration_ms));
536 }
537
CancelScanningTimer()538 void Btm::CancelScanningTimer() { scanning_timer_.Cancel(); }
539
StartObserving()540 void Btm::StartObserving() { StartScanning(kPassiveScanning); }
541
StopObserving()542 void Btm::StopObserving() { StopActiveScanning(); }
543
SetObservingTimer(uint64_t duration_ms,common::OnceCallback<void ()> callback)544 void Btm::SetObservingTimer(uint64_t duration_ms,
545 common::OnceCallback<void()> callback) {
546 observing_timer_.Schedule(std::move(callback),
547 std::chrono::milliseconds(duration_ms));
548 }
549
CancelObservingTimer()550 void Btm::CancelObservingTimer() { observing_timer_.Cancel(); }
551
StartScanning(bool use_active_scanning)552 void Btm::StartScanning(bool use_active_scanning) {
553 GetScanning()->RegisterScanningCallback(&scanning_callbacks_);
554 GetScanning()->Scan(true);
555 }
556
GetNumberOfAdvertisingInstances() const557 size_t Btm::GetNumberOfAdvertisingInstances() const {
558 return GetAdvertising()->GetNumberOfAdvertisingInstances();
559 }
560
CreateBond(const RawAddress & bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,int device_type)561 tBTM_STATUS Btm::CreateBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
562 tBT_TRANSPORT transport, int device_type) {
563 if (transport == BT_TRANSPORT_AUTO) {
564 if (device_type & BT_DEVICE_TYPE_BLE) {
565 transport = BT_TRANSPORT_LE;
566 } else if (device_type & BT_DEVICE_TYPE_BREDR) {
567 transport = BT_TRANSPORT_BR_EDR;
568 }
569 LOG_INFO("%s guessing transport as %02x ", __func__, transport);
570 }
571
572 auto security_manager = GetSecurityModule()->GetSecurityManager();
573 switch (transport) {
574 case BT_TRANSPORT_BR_EDR:
575 security_manager->CreateBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC));
576 break;
577 case BT_TRANSPORT_LE:
578 security_manager->CreateBondLe(ToAddressWithType(bd_addr, addr_type));
579 break;
580 default:
581 return BTM_ILLEGAL_VALUE;
582 }
583 return BTM_CMD_STARTED;
584 }
585
CancelBond(const RawAddress & bd_addr)586 bool Btm::CancelBond(const RawAddress& bd_addr) {
587 auto security_manager = GetSecurityModule()->GetSecurityManager();
588 security_manager->CancelBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC));
589 return true;
590 }
591
RemoveBond(const RawAddress & bd_addr)592 bool Btm::RemoveBond(const RawAddress& bd_addr) {
593 // TODO(cmanton) Check if acl is connected
594 auto security_manager = GetSecurityModule()->GetSecurityManager();
595 security_manager->RemoveBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC));
596 return true;
597 }
598
GetAclHandle(const RawAddress & remote_bda,tBT_TRANSPORT transport)599 uint16_t Btm::GetAclHandle(const RawAddress& remote_bda,
600 tBT_TRANSPORT transport) {
601 auto acl_manager = GetAclManager();
602 if (transport == BT_TRANSPORT_BR_EDR) {
603 return acl_manager->HACK_GetHandle(ToGdAddress(remote_bda));
604 } else {
605 return acl_manager->HACK_GetLeHandle(ToGdAddress(remote_bda));
606 }
607 }
608
GetAddressAndType(const RawAddress & bd_addr)609 hci::AddressWithType Btm::GetAddressAndType(const RawAddress& bd_addr) {
610 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
611 if (p_dev_rec != NULL && p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) {
612 if (!p_dev_rec->ble.identity_address_with_type.bda.IsEmpty()) {
613 return ToAddressWithType(p_dev_rec->ble.identity_address_with_type.bda,
614 p_dev_rec->ble.identity_address_with_type.type);
615 } else {
616 return ToAddressWithType(p_dev_rec->ble.pseudo_addr,
617 p_dev_rec->ble.AddressType());
618 }
619 }
620 LOG(ERROR) << "Unknown bd_addr. Use public address";
621 return ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC);
622 }
623
624 } // namespace shim
625
626 } // namespace bluetooth
627