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