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