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