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