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 <cstddef>
21 #include <cstdint>
22 #include <cstring>
23 #include <mutex>
24
25 #include "main/shim/btm.h"
26 #include "main/shim/controller.h"
27 #include "main/shim/entry.h"
28 #include "main/shim/shim.h"
29 #include "osi/include/log.h"
30 #include "stack/btm/btm_int_types.h"
31 #include "types/class_of_device.h"
32 #include "types/raw_address.h"
33
34 #include "hci/le_advertising_manager.h"
35 #include "hci/le_scanning_manager.h"
36 #include "main/shim/helpers.h"
37 #include "neighbor/connectability.h"
38 #include "neighbor/discoverability.h"
39 #include "neighbor/inquiry.h"
40 #include "neighbor/name.h"
41 #include "neighbor/page.h"
42 #include "security/security_module.h"
43 #include "shim/controller.h"
44
45 extern tBTM_CB btm_cb;
46
47 static constexpr size_t kRemoteDeviceNameLength = 248;
48
49 static constexpr uint8_t kAdvDataInfoNotPresent = 0xff;
50 static constexpr uint8_t kTxPowerInformationNotPresent = 0x7f;
51 static constexpr uint8_t kNotPeriodicAdvertisement = 0x00;
52
53 static constexpr bool kActiveScanning = true;
54 static constexpr bool kPassiveScanning = false;
55
56 using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME;
57
58 extern void btm_process_cancel_complete(uint8_t status, uint8_t mode);
59 extern void btm_process_inq_complete(uint8_t status, uint8_t result_type);
60 extern void btm_ble_process_adv_addr(RawAddress& raw_address,
61 uint8_t* address_type);
62 extern void btm_ble_process_adv_pkt_cont(
63 uint16_t event_type, uint8_t address_type, const RawAddress& raw_address,
64 uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid,
65 int8_t tx_power, int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len,
66 uint8_t* data);
67
68 extern void btm_api_process_inquiry_result(const RawAddress& raw_address,
69 uint8_t page_scan_rep_mode,
70 DEV_CLASS device_class,
71 uint16_t clock_offset);
72
73 extern void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address,
74 uint8_t page_scan_rep_mode,
75 DEV_CLASS device_class,
76 uint16_t clock_offset,
77 int8_t rssi);
78
79 extern void btm_api_process_extended_inquiry_result(
80 RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class,
81 uint16_t clock_offset, int8_t rssi, const uint8_t* eir_data,
82 size_t eir_len);
83
StartUp(bluetooth::shim::Btm * btm)84 void bluetooth::shim::Btm::StartUp(bluetooth::shim::Btm* btm) {
85 CHECK(btm != nullptr);
86 std::unique_lock<std::mutex> lock(btm->sync_mutex_);
87 CHECK(btm->observing_timer_ == nullptr);
88 CHECK(btm->scanning_timer_ == nullptr);
89 btm->observing_timer_ = new bluetooth::shim::Timer("observing_timer");
90 btm->scanning_timer_ = new bluetooth::shim::Timer("scanning_timer");
91
92 }
93
ShutDown(bluetooth::shim::Btm * btm)94 void bluetooth::shim::Btm::ShutDown(bluetooth::shim::Btm* btm) {
95 CHECK(btm != nullptr);
96 std::unique_lock<std::mutex> lock(btm->sync_mutex_);
97 CHECK(btm->observing_timer_ != nullptr);
98 CHECK(btm->scanning_timer_ != nullptr);
99 delete btm->scanning_timer_;
100 delete btm->observing_timer_;
101 btm->scanning_timer_ = nullptr;
102 btm->observing_timer_ = nullptr;
103 }
104
OnInquiryResult(bluetooth::hci::InquiryResultView view)105 void bluetooth::shim::Btm::OnInquiryResult(
106 bluetooth::hci::InquiryResultView view) {
107 for (auto& response : view.GetInquiryResults()) {
108 btm_api_process_inquiry_result(
109 RawAddress(response.bd_addr_.address),
110 static_cast<uint8_t>(response.page_scan_repetition_mode_),
111 response.class_of_device_.cod, response.clock_offset_);
112 }
113 }
114
OnInquiryResultWithRssi(bluetooth::hci::InquiryResultWithRssiView view)115 void bluetooth::shim::Btm::OnInquiryResultWithRssi(
116 bluetooth::hci::InquiryResultWithRssiView view) {
117 for (auto& response : view.GetInquiryResults()) {
118 btm_api_process_inquiry_result_with_rssi(
119 RawAddress(response.address_.address),
120 static_cast<uint8_t>(response.page_scan_repetition_mode_),
121 response.class_of_device_.cod, response.clock_offset_, response.rssi_);
122 }
123 }
124
OnExtendedInquiryResult(bluetooth::hci::ExtendedInquiryResultView view)125 void bluetooth::shim::Btm::OnExtendedInquiryResult(
126 bluetooth::hci::ExtendedInquiryResultView view) {
127 constexpr size_t kMaxExtendedInquiryResponse = 240;
128 uint8_t gap_data_buffer[kMaxExtendedInquiryResponse];
129 uint8_t* data = nullptr;
130 size_t data_len = 0;
131
132 if (!view.GetExtendedInquiryResponse().empty()) {
133 bzero(gap_data_buffer, sizeof(gap_data_buffer));
134 uint8_t* p = gap_data_buffer;
135 for (auto gap_data : view.GetExtendedInquiryResponse()) {
136 *p++ = gap_data.data_.size() + sizeof(gap_data.data_type_);
137 *p++ = static_cast<uint8_t>(gap_data.data_type_);
138 p = (uint8_t*)memcpy(p, &gap_data.data_[0], gap_data.data_.size()) +
139 gap_data.data_.size();
140 }
141 data = gap_data_buffer;
142 data_len = p - data;
143 }
144
145 btm_api_process_extended_inquiry_result(
146 RawAddress(view.GetAddress().address),
147 static_cast<uint8_t>(view.GetPageScanRepetitionMode()),
148 view.GetClassOfDevice().cod, view.GetClockOffset(), view.GetRssi(), data,
149 data_len);
150 }
151
OnInquiryComplete(bluetooth::hci::ErrorCode status)152 void bluetooth::shim::Btm::OnInquiryComplete(bluetooth::hci::ErrorCode status) {
153 limited_inquiry_active_ = false;
154 general_inquiry_active_ = false;
155 legacy_inquiry_complete_callback_((static_cast<uint16_t>(status) == 0)
156 ? (BTM_SUCCESS)
157 : (BTM_ERR_PROCESSING),
158 active_inquiry_mode_);
159
160 active_inquiry_mode_ = kInquiryModeOff;
161 }
162
SetInquiryFilter(uint8_t mode,uint8_t type,tBTM_INQ_FILT_COND data)163 bool bluetooth::shim::Btm::SetInquiryFilter(uint8_t mode, uint8_t type,
164 tBTM_INQ_FILT_COND data) {
165 switch (mode) {
166 case kInquiryModeOff:
167 break;
168 case kLimitedInquiryMode:
169 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
170 break;
171 case kGeneralInquiryMode:
172 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
173 break;
174 default:
175 LOG_WARN(LOG_TAG, "%s Unknown inquiry mode:%d", __func__, mode);
176 return false;
177 }
178 return true;
179 }
180
SetFilterInquiryOnAddress()181 void bluetooth::shim::Btm::SetFilterInquiryOnAddress() {
182 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
183 }
184
SetFilterInquiryOnDevice()185 void bluetooth::shim::Btm::SetFilterInquiryOnDevice() {
186 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
187 }
188
ClearInquiryFilter()189 void bluetooth::shim::Btm::ClearInquiryFilter() {
190 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
191 }
192
SetStandardInquiryResultMode()193 void bluetooth::shim::Btm::SetStandardInquiryResultMode() {
194 bluetooth::shim::GetInquiry()->SetStandardInquiryResultMode();
195 }
196
SetInquiryWithRssiResultMode()197 void bluetooth::shim::Btm::SetInquiryWithRssiResultMode() {
198 bluetooth::shim::GetInquiry()->SetInquiryWithRssiResultMode();
199 }
200
SetExtendedInquiryResultMode()201 void bluetooth::shim::Btm::SetExtendedInquiryResultMode() {
202 bluetooth::shim::GetInquiry()->SetExtendedInquiryResultMode();
203 }
204
SetInterlacedInquiryScan()205 void bluetooth::shim::Btm::SetInterlacedInquiryScan() {
206 bluetooth::shim::GetInquiry()->SetInterlacedScan();
207 }
208
SetStandardInquiryScan()209 void bluetooth::shim::Btm::SetStandardInquiryScan() {
210 bluetooth::shim::GetInquiry()->SetStandardScan();
211 }
212
IsInterlacedScanSupported() const213 bool bluetooth::shim::Btm::IsInterlacedScanSupported() const {
214 return controller_get_interface()->supports_interlaced_inquiry_scan();
215 }
216
217 /**
218 * One shot inquiry
219 */
StartInquiry(uint8_t mode,uint8_t duration,uint8_t max_responses,LegacyInquiryCompleteCallback legacy_inquiry_complete_callback)220 bool bluetooth::shim::Btm::StartInquiry(
221 uint8_t mode, uint8_t duration, uint8_t max_responses,
222 LegacyInquiryCompleteCallback legacy_inquiry_complete_callback) {
223 switch (mode) {
224 case kInquiryModeOff:
225 LOG_DEBUG(LOG_TAG, "%s Stopping inquiry mode", __func__);
226 if (limited_inquiry_active_ || general_inquiry_active_) {
227 bluetooth::shim::GetInquiry()->StopInquiry();
228 limited_inquiry_active_ = false;
229 general_inquiry_active_ = false;
230 }
231 active_inquiry_mode_ = kInquiryModeOff;
232 break;
233
234 case kLimitedInquiryMode:
235 case kGeneralInquiryMode: {
236 if (mode == kLimitedInquiryMode) {
237 LOG_DEBUG(
238 LOG_TAG,
239 "%s Starting limited inquiry mode duration:%hhd max responses:%hhd",
240 __func__, duration, max_responses);
241 limited_inquiry_active_ = true;
242 bluetooth::shim::GetInquiry()->StartLimitedInquiry(duration,
243 max_responses);
244 active_inquiry_mode_ = kLimitedInquiryMode;
245 } else {
246 LOG_DEBUG(
247 LOG_TAG,
248 "%s Starting general inquiry mode duration:%hhd max responses:%hhd",
249 __func__, duration, max_responses);
250 general_inquiry_active_ = true;
251 bluetooth::shim::GetInquiry()->StartGeneralInquiry(duration,
252 max_responses);
253 legacy_inquiry_complete_callback_ = legacy_inquiry_complete_callback;
254 }
255 } break;
256
257 default:
258 LOG_WARN(LOG_TAG, "%s Unknown inquiry mode:%d", __func__, mode);
259 return false;
260 }
261 return true;
262 }
263
CancelInquiry()264 void bluetooth::shim::Btm::CancelInquiry() {
265 LOG_DEBUG(LOG_TAG, "%s", __func__);
266 if (limited_inquiry_active_ || general_inquiry_active_) {
267 bluetooth::shim::GetInquiry()->StopInquiry();
268 limited_inquiry_active_ = false;
269 general_inquiry_active_ = false;
270 }
271 }
272
IsInquiryActive() const273 bool bluetooth::shim::Btm::IsInquiryActive() const {
274 return IsGeneralInquiryActive() || IsLimitedInquiryActive();
275 }
276
IsGeneralInquiryActive() const277 bool bluetooth::shim::Btm::IsGeneralInquiryActive() const {
278 return general_inquiry_active_;
279 }
280
IsLimitedInquiryActive() const281 bool bluetooth::shim::Btm::IsLimitedInquiryActive() const {
282 return limited_inquiry_active_;
283 }
284
285 /**
286 * Periodic
287 */
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)288 bool bluetooth::shim::Btm::StartPeriodicInquiry(
289 uint8_t mode, uint8_t duration, uint8_t max_responses, uint16_t max_delay,
290 uint16_t min_delay, tBTM_INQ_RESULTS_CB* p_results_cb) {
291 switch (mode) {
292 case kInquiryModeOff:
293 limited_periodic_inquiry_active_ = false;
294 general_periodic_inquiry_active_ = false;
295 bluetooth::shim::GetInquiry()->StopPeriodicInquiry();
296 break;
297
298 case kLimitedInquiryMode:
299 case kGeneralInquiryMode: {
300 if (mode == kLimitedInquiryMode) {
301 LOG_DEBUG(LOG_TAG, "%s Starting limited periodic inquiry mode",
302 __func__);
303 limited_periodic_inquiry_active_ = true;
304 bluetooth::shim::GetInquiry()->StartLimitedPeriodicInquiry(
305 duration, max_responses, max_delay, min_delay);
306 } else {
307 LOG_DEBUG(LOG_TAG, "%s Starting general periodic inquiry mode",
308 __func__);
309 general_periodic_inquiry_active_ = true;
310 bluetooth::shim::GetInquiry()->StartGeneralPeriodicInquiry(
311 duration, max_responses, max_delay, min_delay);
312 }
313 } break;
314
315 default:
316 LOG_WARN(LOG_TAG, "%s Unknown inquiry mode:%d", __func__, mode);
317 return false;
318 }
319 return true;
320 }
321
CancelPeriodicInquiry()322 void bluetooth::shim::Btm::CancelPeriodicInquiry() {
323 limited_periodic_inquiry_active_ = false;
324 general_periodic_inquiry_active_ = false;
325 bluetooth::shim::GetInquiry()->StopPeriodicInquiry();
326 }
327
IsGeneralPeriodicInquiryActive() const328 bool bluetooth::shim::Btm::IsGeneralPeriodicInquiryActive() const {
329 return general_periodic_inquiry_active_;
330 }
331
IsLimitedPeriodicInquiryActive() const332 bool bluetooth::shim::Btm::IsLimitedPeriodicInquiryActive() const {
333 return limited_periodic_inquiry_active_;
334 }
335
336 /**
337 * Discoverability
338 */
339
RegisterInquiryCallbacks()340 void bluetooth::shim::Btm::RegisterInquiryCallbacks() {
341 bluetooth::neighbor::InquiryCallbacks inquiry_callbacks;
342 inquiry_callbacks.result =
343 std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1);
344 inquiry_callbacks.result_with_rssi =
345 std::bind(&Btm::OnInquiryResultWithRssi, this, std::placeholders::_1);
346 inquiry_callbacks.extended_result =
347 std::bind(&Btm::OnExtendedInquiryResult, this, std::placeholders::_1);
348 inquiry_callbacks.complete =
349 std::bind(&Btm::OnInquiryComplete, this, std::placeholders::_1);
350 bluetooth::shim::GetInquiry()->RegisterCallbacks(inquiry_callbacks);
351 }
352
353 bluetooth::neighbor::ScanParameters params_{
354 .interval = 0,
355 .window = 0,
356 };
357
SetClassicGeneralDiscoverability(uint16_t window,uint16_t interval)358 void bluetooth::shim::Btm::SetClassicGeneralDiscoverability(uint16_t window,
359 uint16_t interval) {
360 params_.window = window;
361 params_.interval = interval;
362
363 bluetooth::shim::GetInquiry()->SetScanActivity(params_);
364 bluetooth::shim::GetDiscoverability()->StartGeneralDiscoverability();
365 }
366
SetClassicLimitedDiscoverability(uint16_t window,uint16_t interval)367 void bluetooth::shim::Btm::SetClassicLimitedDiscoverability(uint16_t window,
368 uint16_t interval) {
369 params_.window = window;
370 params_.interval = interval;
371 bluetooth::shim::GetInquiry()->SetScanActivity(params_);
372 bluetooth::shim::GetDiscoverability()->StartLimitedDiscoverability();
373 }
374
SetClassicDiscoverabilityOff()375 void bluetooth::shim::Btm::SetClassicDiscoverabilityOff() {
376 bluetooth::shim::GetDiscoverability()->StopDiscoverability();
377 }
378
GetClassicDiscoverabilityState() const379 DiscoverabilityState bluetooth::shim::Btm::GetClassicDiscoverabilityState()
380 const {
381 DiscoverabilityState state{.mode = BTM_NON_DISCOVERABLE,
382 .interval = params_.interval,
383 .window = params_.window};
384
385 if (bluetooth::shim::GetDiscoverability()
386 ->IsGeneralDiscoverabilityEnabled()) {
387 state.mode = BTM_GENERAL_DISCOVERABLE;
388 } else if (bluetooth::shim::GetDiscoverability()
389 ->IsLimitedDiscoverabilityEnabled()) {
390 state.mode = BTM_LIMITED_DISCOVERABLE;
391 }
392 return state;
393 }
394
SetLeGeneralDiscoverability()395 void bluetooth::shim::Btm::SetLeGeneralDiscoverability() {
396 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
397 }
398
SetLeLimitedDiscoverability()399 void bluetooth::shim::Btm::SetLeLimitedDiscoverability() {
400 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
401 }
402
SetLeDiscoverabilityOff()403 void bluetooth::shim::Btm::SetLeDiscoverabilityOff() {
404 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
405 }
406
GetLeDiscoverabilityState() const407 DiscoverabilityState bluetooth::shim::Btm::GetLeDiscoverabilityState() const {
408 DiscoverabilityState state{
409 .mode = kDiscoverableModeOff,
410 .interval = 0,
411 .window = 0,
412 };
413 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
414 return state;
415 }
416
417 /**
418 * Connectability
419 */
SetClassicConnectibleOn()420 void bluetooth::shim::Btm::SetClassicConnectibleOn() {
421 bluetooth::shim::GetConnectability()->StartConnectability();
422 }
423
SetClassicConnectibleOff()424 void bluetooth::shim::Btm::SetClassicConnectibleOff() {
425 bluetooth::shim::GetConnectability()->StopConnectability();
426 }
427
GetClassicConnectabilityState() const428 ConnectabilityState bluetooth::shim::Btm::GetClassicConnectabilityState()
429 const {
430 ConnectabilityState state{.interval = params_.interval,
431 .window = params_.window};
432
433 if (bluetooth::shim::GetConnectability()->IsConnectable()) {
434 state.mode = BTM_CONNECTABLE;
435 } else {
436 state.mode = BTM_NON_CONNECTABLE;
437 }
438 return state;
439 }
440
SetInterlacedPageScan()441 void bluetooth::shim::Btm::SetInterlacedPageScan() {
442 bluetooth::shim::GetPage()->SetInterlacedScan();
443 }
444
SetStandardPageScan()445 void bluetooth::shim::Btm::SetStandardPageScan() {
446 bluetooth::shim::GetPage()->SetStandardScan();
447 }
448
SetLeConnectibleOn()449 void bluetooth::shim::Btm::SetLeConnectibleOn() {
450 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
451 }
452
SetLeConnectibleOff()453 void bluetooth::shim::Btm::SetLeConnectibleOff() {
454 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
455 }
456
GetLeConnectabilityState() const457 ConnectabilityState bluetooth::shim::Btm::GetLeConnectabilityState() const {
458 ConnectabilityState state{
459 .mode = kConnectibleModeOff,
460 .interval = 0,
461 .window = 0,
462 };
463 LOG_WARN(LOG_TAG, "UNIMPLEMENTED %s", __func__);
464 return state;
465 }
466
IsLeAclConnected(const RawAddress & raw_address) const467 bool bluetooth::shim::Btm::IsLeAclConnected(
468 const RawAddress& raw_address) const {
469 // TODO(cmanton) Check current acl's for this address and indicate if there is
470 // an LE option. For now ignore and default to classic.
471 LOG_INFO(LOG_TAG, "%s Le acl connection check is temporarily unsupported",
472 __func__);
473 return false;
474 }
475
ReadClassicRemoteDeviceName(const RawAddress & raw_address,tBTM_CMPL_CB * callback)476 bluetooth::shim::BtmStatus bluetooth::shim::Btm::ReadClassicRemoteDeviceName(
477 const RawAddress& raw_address, tBTM_CMPL_CB* callback) {
478 if (!CheckClassicAclLink(raw_address)) {
479 return bluetooth::shim::BTM_UNKNOWN_ADDR;
480 }
481
482 if (!classic_read_remote_name_.Start(raw_address)) {
483 LOG_INFO(LOG_TAG, "%s Read remote name is currently busy address:%s",
484 __func__, raw_address.ToString().c_str());
485 return bluetooth::shim::BTM_BUSY;
486 }
487
488 LOG_DEBUG(LOG_TAG, "%s Start read name from address:%s", __func__,
489 raw_address.ToString().c_str());
490 bluetooth::shim::GetName()->ReadRemoteNameRequest(
491 hci::Address(raw_address.address), hci::PageScanRepetitionMode::R1,
492 0 /* clock_offset */, hci::ClockOffsetValid::INVALID,
493
494 base::Bind(
495 [](tBTM_CMPL_CB* callback, ReadRemoteName* classic_read_remote_name_,
496 hci::ErrorCode status, hci::Address address,
497 std::array<uint8_t, kRemoteDeviceNameLength> remote_name) {
498 RawAddress raw_address(address.address);
499
500 BtmRemoteDeviceName name{
501 .status = (static_cast<uint8_t>(status) == 0)
502 ? (BTM_SUCCESS)
503 : (BTM_BAD_VALUE_RET),
504 .bd_addr = raw_address,
505 .length = kRemoteDeviceNameLength,
506 };
507 std::copy(remote_name.begin(), remote_name.end(),
508 name.remote_bd_name);
509 LOG_DEBUG(LOG_TAG, "%s Finish read name from address:%s name:%s",
510 __func__, address.ToString().c_str(),
511 name.remote_bd_name);
512 callback(&name);
513 classic_read_remote_name_->Stop();
514 },
515 callback, &classic_read_remote_name_),
516 bluetooth::shim::GetGdShimHandler());
517 return bluetooth::shim::BTM_CMD_STARTED;
518 }
519
ReadLeRemoteDeviceName(const RawAddress & raw_address,tBTM_CMPL_CB * callback)520 bluetooth::shim::BtmStatus bluetooth::shim::Btm::ReadLeRemoteDeviceName(
521 const RawAddress& raw_address, tBTM_CMPL_CB* callback) {
522 if (!CheckLeAclLink(raw_address)) {
523 return bluetooth::shim::BTM_UNKNOWN_ADDR;
524 }
525
526 if (!le_read_remote_name_.Start(raw_address)) {
527 return bluetooth::shim::BTM_BUSY;
528 }
529
530 LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s need access to GATT module", __func__);
531 return bluetooth::shim::BTM_UNKNOWN_ADDR;
532 }
533
534 bluetooth::shim::BtmStatus
CancelAllReadRemoteDeviceName()535 bluetooth::shim::Btm::CancelAllReadRemoteDeviceName() {
536 if (classic_read_remote_name_.IsInProgress() ||
537 le_read_remote_name_.IsInProgress()) {
538 if (classic_read_remote_name_.IsInProgress()) {
539 hci::Address address;
540 hci::Address::FromString(classic_read_remote_name_.AddressString(),
541 address);
542
543 bluetooth::shim::GetName()->CancelRemoteNameRequest(
544 address,
545 common::BindOnce(
546 [](ReadRemoteName* classic_read_remote_name_,
547 hci::ErrorCode status,
548 hci::Address address) { classic_read_remote_name_->Stop(); },
549 &classic_read_remote_name_),
550 bluetooth::shim::GetGdShimHandler());
551 }
552 if (le_read_remote_name_.IsInProgress()) {
553 LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s need access to GATT module",
554 __func__);
555 }
556 return bluetooth::shim::BTM_UNKNOWN_ADDR;
557 }
558 LOG_WARN(LOG_TAG,
559 "%s Cancelling classic remote device name without one in progress",
560 __func__);
561 return bluetooth::shim::BTM_WRONG_MODE;
562 }
563
StartAdvertising()564 void bluetooth::shim::Btm::StartAdvertising() {
565 if (advertiser_id_ == hci::LeAdvertisingManager::kInvalidId) {
566 LOG_WARN(LOG_TAG,
567 "%s Already advertising; please stop prior to starting again",
568 __func__);
569 return;
570 }
571
572 hci::AdvertisingConfig config;
573 advertiser_id_ = bluetooth::shim::GetAdvertising()->CreateAdvertiser(
574 config, common::Bind([](hci::Address, hci::AddressType) { /*OnScan*/ }),
575 common::Bind([](hci::ErrorCode, uint8_t, uint8_t) { /*OnTerminated*/ }),
576 bluetooth::shim::GetGdShimHandler());
577 if (advertiser_id_ == hci::LeAdvertisingManager::kInvalidId) {
578 LOG_WARN(LOG_TAG, "%s Unable to start advertising", __func__);
579 return;
580 }
581 LOG_DEBUG(LOG_TAG, "%s Started advertising", __func__);
582 }
583
StopAdvertising()584 void bluetooth::shim::Btm::StopAdvertising() {
585 if (advertiser_id_ == hci::LeAdvertisingManager::kInvalidId) {
586 LOG_WARN(LOG_TAG, "%s No active advertising", __func__);
587 return;
588 }
589 bluetooth::shim::GetAdvertising()->RemoveAdvertiser(advertiser_id_);
590 advertiser_id_ = hci::LeAdvertisingManager::kInvalidId;
591 LOG_DEBUG(LOG_TAG, "%s Stopped advertising", __func__);
592 }
593
StartConnectability()594 void bluetooth::shim::Btm::StartConnectability() { StartAdvertising(); }
595
StopConnectability()596 void bluetooth::shim::Btm::StopConnectability() { StopAdvertising(); }
597
StartActiveScanning()598 void bluetooth::shim::Btm::StartActiveScanning() {
599 StartScanning(kActiveScanning);
600 }
601
StopActiveScanning()602 void bluetooth::shim::Btm::StopActiveScanning() {
603 bluetooth::shim::GetScanning()->StopScan(base::Bind([]() {}));
604 }
605
SetScanningTimer(uint64_t duration_ms,std::function<void ()> func)606 void bluetooth::shim::Btm::SetScanningTimer(uint64_t duration_ms,
607 std::function<void()> func) {
608 scanning_timer_->Set(duration_ms, func);
609 }
610
CancelScanningTimer()611 void bluetooth::shim::Btm::CancelScanningTimer() { scanning_timer_->Cancel(); }
612
StartObserving()613 void bluetooth::shim::Btm::StartObserving() { StartScanning(kPassiveScanning); }
614
StopObserving()615 void bluetooth::shim::Btm::StopObserving() { StopActiveScanning(); }
616
SetObservingTimer(uint64_t duration_ms,std::function<void ()> func)617 void bluetooth::shim::Btm::SetObservingTimer(uint64_t duration_ms,
618 std::function<void()> func) {
619 observing_timer_->Set(duration_ms, func);
620 }
621
CancelObservingTimer()622 void bluetooth::shim::Btm::CancelObservingTimer() {
623 observing_timer_->Cancel();
624 }
625
626 namespace bluetooth {
627 namespace hci {
628
629 constexpr int kAdvertisingReportBufferSize = 1024;
630
631 struct ExtendedEventTypeOptions {
632 bool connectable{false};
633 bool scannable{false};
634 bool directed{false};
635 bool scan_response{false};
636 bool legacy{false};
637 bool continuing{false};
638 bool truncated{false};
639 };
640
641 constexpr uint16_t kBleEventConnectableBit =
642 (0x0001 << 0); // BLE_EVT_CONNECTABLE_BIT
643 constexpr uint16_t kBleEventScannableBit =
644 (0x0001 << 1); // BLE_EVT_SCANNABLE_BIT
645 constexpr uint16_t kBleEventDirectedBit =
646 (0x0001 << 2); // BLE_EVT_DIRECTED_BIT
647 constexpr uint16_t kBleEventScanResponseBit =
648 (0x0001 << 3); // BLE_EVT_SCAN_RESPONSE_BIT
649 constexpr uint16_t kBleEventLegacyBit = (0x0001 << 4); // BLE_EVT_LEGACY_BIT
650 constexpr uint16_t kBleEventIncompleteContinuing = (0x0001 << 5);
651 constexpr uint16_t kBleEventIncompleteTruncated = (0x0001 << 6);
652
TransformToExtendedEventType(uint16_t * extended_event_type,ExtendedEventTypeOptions o)653 static void TransformToExtendedEventType(uint16_t* extended_event_type,
654 ExtendedEventTypeOptions o) {
655 ASSERT(extended_event_type != nullptr);
656 *extended_event_type = (o.connectable ? kBleEventConnectableBit : 0) |
657 (o.scannable ? kBleEventScannableBit : 0) |
658 (o.directed ? kBleEventDirectedBit : 0) |
659 (o.scan_response ? kBleEventScanResponseBit : 0) |
660 (o.legacy ? kBleEventLegacyBit : 0) |
661 (o.continuing ? kBleEventIncompleteContinuing : 0) |
662 (o.truncated ? kBleEventIncompleteTruncated : 0);
663 }
664
665 class BtmScanningCallbacks : public bluetooth::hci::LeScanningManagerCallbacks {
666 public:
on_advertisements(std::vector<std::shared_ptr<LeReport>> reports)667 virtual void on_advertisements(
668 std::vector<std::shared_ptr<LeReport>> reports) {
669 for (auto le_report : reports) {
670 uint8_t address_type = static_cast<uint8_t>(le_report->address_type_);
671 uint16_t extended_event_type = 0;
672 uint8_t* report_data = nullptr;
673 size_t report_len = 0;
674
675 uint8_t advertising_data_buffer[kAdvertisingReportBufferSize];
676 // Copy gap data, if any, into temporary buffer as payload for legacy
677 // stack.
678 if (!le_report->gap_data_.empty()) {
679 bzero(advertising_data_buffer, kAdvertisingReportBufferSize);
680 uint8_t* p = advertising_data_buffer;
681 for (auto gap_data : le_report->gap_data_) {
682 *p++ = gap_data.data_.size() + sizeof(gap_data.data_type_);
683 *p++ = static_cast<uint8_t>(gap_data.data_type_);
684 p = (uint8_t*)memcpy(p, &gap_data.data_[0], gap_data.data_.size()) +
685 gap_data.data_.size();
686 }
687 report_data = advertising_data_buffer;
688 report_len = p - report_data;
689 }
690
691 switch (le_report->GetReportType()) {
692 case hci::LeReport::ReportType::ADVERTISING_EVENT: {
693 switch (le_report->advertising_event_type_) {
694 case hci::AdvertisingEventType::ADV_IND:
695 TransformToExtendedEventType(
696 &extended_event_type,
697 {.connectable = true, .scannable = true, .legacy = true});
698 break;
699 case hci::AdvertisingEventType::ADV_DIRECT_IND:
700 TransformToExtendedEventType(
701 &extended_event_type,
702 {.connectable = true, .directed = true, .legacy = true});
703 break;
704 case hci::AdvertisingEventType::ADV_SCAN_IND:
705 TransformToExtendedEventType(&extended_event_type,
706 {.scannable = true, .legacy = true});
707 break;
708 case hci::AdvertisingEventType::ADV_NONCONN_IND:
709 TransformToExtendedEventType(&extended_event_type,
710 {.legacy = true});
711 break;
712 case hci::AdvertisingEventType::
713 ADV_DIRECT_IND_LOW: // SCAN_RESPONSE
714 TransformToExtendedEventType(&extended_event_type,
715 {.connectable = true,
716 .scannable = true,
717 .scan_response = true,
718 .legacy = true});
719 break;
720 default:
721 LOG_WARN(
722 LOG_TAG, "%s Unsupported event type:%s", __func__,
723 AdvertisingEventTypeText(le_report->advertising_event_type_)
724 .c_str());
725 return;
726 }
727
728 RawAddress raw_address(le_report->address_.address);
729
730 btm_ble_process_adv_addr(raw_address, &address_type);
731 btm_ble_process_adv_pkt_cont(
732 extended_event_type, address_type, raw_address,
733 kPhyConnectionLe1M, kPhyConnectionNone, kAdvDataInfoNotPresent,
734 kTxPowerInformationNotPresent, le_report->rssi_,
735 kNotPeriodicAdvertisement, report_len, report_data);
736 } break;
737
738 case hci::LeReport::ReportType::DIRECTED_ADVERTISING_EVENT:
739 LOG_WARN(LOG_TAG,
740 "%s Directed advertising is unsupported from device:%s",
741 __func__, le_report->address_.ToString().c_str());
742 break;
743
744 case hci::LeReport::ReportType::EXTENDED_ADVERTISING_EVENT: {
745 std::shared_ptr<hci::ExtendedLeReport> extended_le_report =
746 std::static_pointer_cast<hci::ExtendedLeReport>(le_report);
747 TransformToExtendedEventType(
748 &extended_event_type,
749 {.connectable = extended_le_report->connectable_,
750 .scannable = extended_le_report->scannable_,
751 .directed = extended_le_report->directed_,
752 .scan_response = extended_le_report->scan_response_,
753 .legacy = false,
754 .continuing = !extended_le_report->complete_,
755 .truncated = extended_le_report->truncated_});
756 RawAddress raw_address(le_report->address_.address);
757 if (address_type != BLE_ADDR_ANONYMOUS) {
758 btm_ble_process_adv_addr(raw_address, &address_type);
759 }
760 btm_ble_process_adv_pkt_cont(
761 extended_event_type, address_type, raw_address,
762 kPhyConnectionLe1M, kPhyConnectionNone, kAdvDataInfoNotPresent,
763 kTxPowerInformationNotPresent, le_report->rssi_,
764 kNotPeriodicAdvertisement, report_len, report_data);
765
766 } break;
767 }
768 }
769 }
770
on_timeout()771 virtual void on_timeout() {
772 LOG_WARN(LOG_TAG, "%s Scanning timeout", __func__);
773 }
Handler()774 os::Handler* Handler() { return bluetooth::shim::GetGdShimHandler(); }
775 };
776 } // namespace hci
777 } // namespace bluetooth
778
779 bluetooth::hci::BtmScanningCallbacks btm_scanning_callbacks;
780
StartScanning(bool use_active_scanning)781 void bluetooth::shim::Btm::StartScanning(bool use_active_scanning) {
782 bluetooth::shim::GetScanning()->StartScan(&btm_scanning_callbacks);
783 }
784
GetNumberOfAdvertisingInstances() const785 size_t bluetooth::shim::Btm::GetNumberOfAdvertisingInstances() const {
786 return bluetooth::shim::GetAdvertising()->GetNumberOfAdvertisingInstances();
787 }
788
CreateBond(const RawAddress & bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,uint8_t pin_len,uint8_t * p_pin,uint32_t trusted_mask[])789 tBTM_STATUS bluetooth::shim::Btm::CreateBond(const RawAddress& bd_addr,
790 tBLE_ADDR_TYPE addr_type,
791 tBT_TRANSPORT transport,
792 uint8_t pin_len, uint8_t* p_pin,
793 uint32_t trusted_mask[]) {
794 auto security_manager =
795 bluetooth::shim::GetSecurityModule()->GetSecurityManager();
796 switch (transport) {
797 case BT_TRANSPORT_BR_EDR:
798 security_manager->CreateBond(
799 ToAddressWithType(bd_addr.address, BLE_ADDR_PUBLIC));
800 break;
801 case BT_TRANSPORT_LE:
802 security_manager->CreateBondLe(ToAddressWithType(bd_addr, addr_type));
803 break;
804 default:
805 return bluetooth::shim::BTM_ILLEGAL_VALUE;
806 }
807 return bluetooth::shim::BTM_SUCCESS;
808 }
809
CancelBond(const RawAddress & bd_addr)810 bool bluetooth::shim::Btm::CancelBond(const RawAddress& bd_addr) {
811 auto security_manager =
812 bluetooth::shim::GetSecurityModule()->GetSecurityManager();
813 security_manager->CancelBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC));
814 return true;
815 }
816
RemoveBond(const RawAddress & bd_addr)817 bool bluetooth::shim::Btm::RemoveBond(const RawAddress& bd_addr) {
818 // TODO(cmanton) Check if acl is connected
819 auto security_manager =
820 bluetooth::shim::GetSecurityModule()->GetSecurityManager();
821 security_manager->RemoveBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC));
822 return true;
823 }
824
SetSimplePairingCallback(tBTM_SP_CALLBACK * callback)825 void bluetooth::shim::Btm::SetSimplePairingCallback(
826 tBTM_SP_CALLBACK* callback) {
827 auto security_manager =
828 bluetooth::shim::GetSecurityModule()->GetSecurityManager();
829 simple_pairing_callback_ = callback;
830 }
831