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 #pragma once 18 19 #include <cstddef> 20 #include <cstdint> 21 #include <functional> 22 #include <mutex> 23 #include <unordered_map> 24 #include <vector> 25 26 #include "hci/hci_packets.h" 27 28 #include "stack/include/btm_api_types.h" 29 #include "types/raw_address.h" 30 31 #include "gd/common/callback.h" 32 #include "gd/hci/le_advertising_manager.h" 33 #include "gd/hci/le_scanning_manager.h" 34 #include "gd/neighbor/inquiry.h" 35 #include "gd/os/alarm.h" 36 37 // 38 // NOTE: limited and general constants for inquiry and discoverable are swapped 39 // 40 41 /* Discoverable modes */ 42 static constexpr int kDiscoverableModeOff = 0; // BTM_NON_DISCOVERABLE 43 static constexpr int kLimitedDiscoverableMode = 1; // BTM_LIMITED_DISCOVERABLE 44 static constexpr int kGeneralDiscoverableMode = 2; // BTM_GENERAL_DISCOVERABLE 45 46 /* Inquiry modes */ 47 static constexpr uint8_t kInquiryModeOff = 0; // BTM_INQUIRY_NONE 48 static constexpr uint8_t kGeneralInquiryMode = 1; // BTM_GENERAL_INQUIRY 49 static constexpr uint8_t kLimitedInquiryMode = 2; // BTM_LIMITED_INQUIRY 50 51 /* Connectable modes */ 52 static constexpr int kConnectibleModeOff = 0; // BTM_NON_CONNECTABLE 53 static constexpr int kConnectibleModeOn = 1; // BTM_CONNECTABLE 54 55 /* Inquiry and page scan modes */ 56 static constexpr int kStandardScanType = 0; 57 static constexpr int kInterlacedScanType = 1; 58 59 /* Inquiry result modes */ 60 static constexpr int kStandardInquiryResult = 0; 61 static constexpr int kInquiryResultWithRssi = 1; 62 static constexpr int kExtendedInquiryResult = 2; 63 64 /* Inquiry filter types */ 65 static constexpr int kClearInquiryFilter = 0; 66 static constexpr int kFilterOnDeviceClass = 1; 67 static constexpr int kFilterOnAddress = 2; 68 69 static constexpr uint8_t kPhyConnectionNone = 0x00; 70 static constexpr uint8_t kPhyConnectionLe1M = 0x01; 71 static constexpr uint8_t kPhyConnectionLe2M = 0x02; 72 static constexpr uint8_t kPhyConnectionLeCoded = 0x03; 73 74 using LegacyInquiryCompleteCallback = 75 std::function<void(uint16_t status, uint8_t inquiry_mode)>; 76 77 using DiscoverabilityState = struct { 78 int mode; 79 uint16_t interval; 80 uint16_t window; 81 }; 82 using ConnectabilityState = DiscoverabilityState; 83 84 namespace bluetooth { 85 namespace shim { 86 87 using BtmStatus = enum : uint16_t { 88 BTM_SUCCESS = 0, /* Command succeeded */ 89 BTM_CMD_STARTED = 1, /* Command started OK. */ 90 BTM_BUSY = 2, /* Device busy with another command */ 91 BTM_NO_RESOURCES = 3, /* No resources to issue command */ 92 BTM_MODE_UNSUPPORTED = 4, /* Request for 1 or more unsupported modes */ 93 BTM_ILLEGAL_VALUE = 5, /* Illegal parameter value */ 94 BTM_WRONG_MODE = 6, /* Device in wrong mode for request */ 95 BTM_UNKNOWN_ADDR = 7, /* Unknown remote BD address */ 96 BTM_DEVICE_TIMEOUT = 8, /* Device timeout */ 97 BTM_BAD_VALUE_RET = 9, /* A bad value was received from HCI */ 98 BTM_ERR_PROCESSING = 10, /* Generic error */ 99 BTM_NOT_AUTHORIZED = 11, /* Authorization failed */ 100 BTM_DEV_RESET = 12, /* Device has been reset */ 101 BTM_CMD_STORED = 13, /* request is stored in control block */ 102 BTM_ILLEGAL_ACTION = 14, /* state machine gets illegal command */ 103 BTM_DELAY_CHECK = 15, /* delay the check on encryption */ 104 BTM_SCO_BAD_LENGTH = 16, /* Bad SCO over HCI data length */ 105 BTM_SUCCESS_NO_SECURITY = 17, /* security passed, no security set */ 106 BTM_FAILED_ON_SECURITY = 18, /* security failed */ 107 BTM_REPEATED_ATTEMPTS = 19, /* repeated attempts for LE security requests */ 108 BTM_MODE4_LEVEL4_NOT_SUPPORTED = 20, /* Secure Connections Only Mode can't be 109 supported */ 110 BTM_DEV_BLACKLISTED = 21, /* The device is Blacklisted */ 111 }; 112 113 class Btm { 114 public: 115 // |handler| is used to run timer tasks and scan callbacks 116 Btm(os::Handler* handler, neighbor::InquiryModule* inquiry); 117 ~Btm() = default; 118 119 // Inquiry result callbacks 120 void OnInquiryResult(bluetooth::hci::InquiryResultView view); 121 void OnInquiryResultWithRssi(bluetooth::hci::InquiryResultWithRssiView view); 122 void OnExtendedInquiryResult(bluetooth::hci::ExtendedInquiryResultView view); 123 void OnInquiryComplete(bluetooth::hci::ErrorCode status); 124 125 // Inquiry API 126 bool SetInquiryFilter(uint8_t mode, uint8_t type, tBTM_INQ_FILT_COND data); 127 void SetFilterInquiryOnAddress(); 128 void SetFilterInquiryOnDevice(); 129 void ClearInquiryFilter(); 130 131 void SetStandardInquiryResultMode(); 132 void SetInquiryWithRssiResultMode(); 133 void SetExtendedInquiryResultMode(); 134 135 void SetInterlacedInquiryScan(); 136 void SetStandardInquiryScan(); 137 bool IsInterlacedScanSupported() const; 138 139 bool StartInquiry(uint8_t mode, uint8_t duration, uint8_t max_responses, 140 LegacyInquiryCompleteCallback inquiry_complete_callback); 141 void CancelInquiry(); 142 bool IsInquiryActive() const; 143 bool IsGeneralInquiryActive() const; 144 bool IsLimitedInquiryActive() const; 145 146 bool StartPeriodicInquiry(uint8_t mode, uint8_t duration, 147 uint8_t max_responses, uint16_t max_delay, 148 uint16_t min_delay, 149 tBTM_INQ_RESULTS_CB* p_results_cb); 150 void CancelPeriodicInquiry(); 151 bool IsGeneralPeriodicInquiryActive() const; 152 bool IsLimitedPeriodicInquiryActive() const; 153 154 // Discoverability API 155 bool general_inquiry_active_{false}; 156 bool limited_inquiry_active_{false}; 157 bool general_periodic_inquiry_active_{false}; 158 bool limited_periodic_inquiry_active_{false}; 159 void SetClassicGeneralDiscoverability(uint16_t window, uint16_t interval); 160 void SetClassicLimitedDiscoverability(uint16_t window, uint16_t interval); 161 void SetClassicDiscoverabilityOff(); 162 DiscoverabilityState GetClassicDiscoverabilityState() const; 163 164 void SetLeGeneralDiscoverability(); 165 void SetLeLimitedDiscoverability(); 166 void SetLeDiscoverabilityOff(); 167 DiscoverabilityState GetLeDiscoverabilityState() const; 168 169 void SetClassicConnectibleOn(); 170 void SetClassicConnectibleOff(); 171 ConnectabilityState GetClassicConnectabilityState() const; 172 void SetInterlacedPageScan(); 173 void SetStandardPageScan(); 174 175 void SetLeConnectibleOn(); 176 void SetLeConnectibleOff(); 177 ConnectabilityState GetLeConnectabilityState() const; 178 179 bool UseLeLink(const RawAddress& raw_address) const; 180 181 // Remote device name API 182 BtmStatus ReadClassicRemoteDeviceName(const RawAddress& raw_address, 183 tBTM_CMPL_CB* callback); 184 BtmStatus ReadLeRemoteDeviceName(const RawAddress& raw_address, 185 tBTM_CMPL_CB* callback); 186 BtmStatus CancelAllReadRemoteDeviceName(); 187 188 // Le neighbor interaction API 189 bluetooth::hci::AdvertiserId advertiser_id_{ 190 hci::LeAdvertisingManager::kInvalidId}; 191 void StartAdvertising(); 192 void StopAdvertising(); 193 void StartConnectability(); 194 void StopConnectability(); 195 196 void StartActiveScanning(); 197 void StopActiveScanning(); 198 199 void StartObserving(); 200 void StopObserving(); 201 202 size_t GetNumberOfAdvertisingInstances() const; 203 204 void SetObservingTimer(uint64_t duration_ms, 205 common::OnceCallback<void()> callback); 206 void CancelObservingTimer(); 207 void SetScanningTimer(uint64_t duration_ms, 208 common::OnceCallback<void()> callback); 209 void CancelScanningTimer(); 210 211 tBTM_STATUS CreateBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, 212 tBT_TRANSPORT transport, int device_type); 213 bool CancelBond(const RawAddress& bd_addr); 214 bool RemoveBond(const RawAddress& bd_addr); 215 216 uint16_t GetAclHandle(const RawAddress& remote_bda, tBT_TRANSPORT transport); 217 218 static tBLE_ADDR_TYPE GetAddressType(const RawAddress& bd_addr); 219 220 // Store the address type from advertising report or connection complete 221 // packet. 222 // TODO(b/161319293): Obtain from storage 223 static void StoreAddressType(const RawAddress& bd_addr, tBLE_ADDR_TYPE type); 224 225 private: 226 os::Alarm scanning_timer_; 227 os::Alarm observing_timer_; 228 229 LegacyInquiryCompleteCallback legacy_inquiry_complete_callback_{}; 230 uint8_t active_inquiry_mode_ = 0; 231 232 class ReadRemoteName { 233 public: 234 ReadRemoteName() = default; 235 bool Start(RawAddress raw_address); 236 void Stop(); 237 bool IsInProgress() const; 238 std::string AddressString() const; 239 240 private: 241 std::mutex mutex_; 242 bool in_progress_ = false; 243 RawAddress raw_address_ = RawAddress::kEmpty; 244 }; 245 ReadRemoteName le_read_remote_name_; 246 ReadRemoteName classic_read_remote_name_; 247 248 class ScanningCallbacks : public hci::LeScanningManagerCallbacks { 249 void on_advertisements( 250 std::vector<std::shared_ptr<hci::LeReport>> reports) override; 251 void on_timeout() override; 252 os::Handler* Handler() override; 253 }; 254 ScanningCallbacks scanning_callbacks_; 255 256 // TODO(cmanton) abort if there is no classic acl link up CheckClassicAclLink(const RawAddress & raw_address)257 bool CheckClassicAclLink(const RawAddress& raw_address) { return true; } CheckLeAclLink(const RawAddress & raw_address)258 bool CheckLeAclLink(const RawAddress& raw_address) { return true; } 259 void StartScanning(bool use_active_scanning); 260 }; 261 262 } // namespace shim 263 } // namespace bluetooth 264