• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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