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