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