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/btm/neighbor_inquiry.h"
29 #include "stack/include/btm_api_types.h"
30 #include "types/raw_address.h"
31 
32 #include "gd/common/callback.h"
33 #include "gd/hci/le_advertising_manager.h"
34 #include "gd/hci/le_scanning_manager.h"
35 #include "gd/neighbor/inquiry.h"
36 #include "gd/os/alarm.h"
37 
38 //
39 // NOTE: limited and general constants for inquiry and discoverable are swapped
40 //
41 
42 /* Discoverable modes */
43 static constexpr int kDiscoverableModeOff = 0;      // BTM_NON_DISCOVERABLE
44 static constexpr int kLimitedDiscoverableMode = 1;  // BTM_LIMITED_DISCOVERABLE
45 static constexpr int kGeneralDiscoverableMode = 2;  // BTM_GENERAL_DISCOVERABLE
46 
47 /* Inquiry modes */
48 static constexpr uint8_t kInquiryModeOff = 0;      // BTM_INQUIRY_NONE
49 static constexpr uint8_t kGeneralInquiryMode = 1;  // BTM_GENERAL_INQUIRY
50 static constexpr uint8_t kLimitedInquiryMode = 2;  // BTM_LIMITED_INQUIRY
51 
52 /* Connectable modes */
53 static constexpr int kConnectibleModeOff = 0;  // BTM_NON_CONNECTABLE
54 static constexpr int kConnectibleModeOn = 1;   // BTM_CONNECTABLE
55 
56 /* Inquiry and page scan modes */
57 static constexpr int kStandardScanType = 0;
58 static constexpr int kInterlacedScanType = 1;
59 
60 /* Inquiry result modes */
61 static constexpr int kStandardInquiryResult = 0;
62 static constexpr int kInquiryResultWithRssi = 1;
63 static constexpr int kExtendedInquiryResult = 2;
64 
65 static constexpr uint8_t kPhyConnectionNone = 0x00;
66 static constexpr uint8_t kPhyConnectionLe1M = 0x01;
67 static constexpr uint8_t kPhyConnectionLe2M = 0x02;
68 static constexpr uint8_t kPhyConnectionLeCoded = 0x03;
69 
70 using LegacyInquiryCompleteCallback =
71     std::function<void(tBTM_STATUS status, uint8_t inquiry_mode)>;
72 
73 using DiscoverabilityState = struct {
74   int mode;
75   uint16_t interval;
76   uint16_t window;
77 };
78 using ConnectabilityState = DiscoverabilityState;
79 
80 using HACK_ScoDisconnectCallback = std::function<void(uint16_t, uint8_t)>;
81 
82 using BtmStatus = tBTM_STATUS;
83 
84 namespace bluetooth {
85 namespace shim {
86 
87 class Btm {
88  public:
89   // |handler| is used to run timer tasks and scan callbacks
90   Btm(os::Handler* handler, neighbor::InquiryModule* inquiry);
91   ~Btm() = default;
92 
93   // Inquiry result callbacks
94   void OnInquiryResult(bluetooth::hci::InquiryResultView view);
95   void OnInquiryResultWithRssi(bluetooth::hci::InquiryResultWithRssiView view);
96   void OnExtendedInquiryResult(bluetooth::hci::ExtendedInquiryResultView view);
97   void OnInquiryComplete(bluetooth::hci::ErrorCode status);
98 
99   void SetStandardInquiryResultMode();
100   void SetInquiryWithRssiResultMode();
101   void SetExtendedInquiryResultMode();
102 
103   void SetInterlacedInquiryScan();
104   void SetStandardInquiryScan();
105   bool IsInterlacedScanSupported() const;
106 
107   bool StartInquiry(uint8_t mode, uint8_t duration, uint8_t max_responses,
108                     LegacyInquiryCompleteCallback inquiry_complete_callback);
109   void CancelInquiry();
110   bool IsInquiryActive() const;
111   bool IsGeneralInquiryActive() const;
112   bool IsLimitedInquiryActive() const;
113 
114   bool StartPeriodicInquiry(uint8_t mode, uint8_t duration,
115                             uint8_t max_responses, uint16_t max_delay,
116                             uint16_t min_delay,
117                             tBTM_INQ_RESULTS_CB* p_results_cb);
118   void CancelPeriodicInquiry();
119   bool IsGeneralPeriodicInquiryActive() const;
120   bool IsLimitedPeriodicInquiryActive() const;
121 
122   // Discoverability API
123   bool general_inquiry_active_{false};
124   bool limited_inquiry_active_{false};
125   bool general_periodic_inquiry_active_{false};
126   bool limited_periodic_inquiry_active_{false};
127   void SetClassicGeneralDiscoverability(uint16_t window, uint16_t interval);
128   void SetClassicLimitedDiscoverability(uint16_t window, uint16_t interval);
129   void SetClassicDiscoverabilityOff();
130   DiscoverabilityState GetClassicDiscoverabilityState() const;
131 
132   void SetLeGeneralDiscoverability();
133   void SetLeLimitedDiscoverability();
134   void SetLeDiscoverabilityOff();
135   DiscoverabilityState GetLeDiscoverabilityState() const;
136 
137   void SetClassicConnectibleOn();
138   void SetClassicConnectibleOff();
139   ConnectabilityState GetClassicConnectabilityState() const;
140   void SetInterlacedPageScan();
141   void SetStandardPageScan();
142 
143   void SetLeConnectibleOn();
144   void SetLeConnectibleOff();
145   ConnectabilityState GetLeConnectabilityState() const;
146 
147   bool UseLeLink(const RawAddress& raw_address) const;
148 
149   // Remote device name API
150   BtmStatus ReadClassicRemoteDeviceName(const RawAddress& raw_address,
151                                         tBTM_CMPL_CB* callback);
152   BtmStatus ReadLeRemoteDeviceName(const RawAddress& raw_address,
153                                    tBTM_CMPL_CB* callback);
154   BtmStatus CancelAllReadRemoteDeviceName();
155 
156   // Le neighbor interaction API
157   bluetooth::hci::AdvertiserId advertiser_id_{
158       hci::LeAdvertisingManager::kInvalidId};
159   void StartAdvertising();
160   void StopAdvertising();
161   void StartConnectability();
162   void StopConnectability();
163 
164   void StartActiveScanning();
165   void StopActiveScanning();
166 
167   void StartObserving();
168   void StopObserving();
169 
170   size_t GetNumberOfAdvertisingInstances() const;
171 
172   void SetObservingTimer(uint64_t duration_ms,
173                          common::OnceCallback<void()> callback);
174   void CancelObservingTimer();
175   void SetScanningTimer(uint64_t duration_ms,
176                         common::OnceCallback<void()> callback);
177   void CancelScanningTimer();
178 
179   tBTM_STATUS CreateBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
180                          tBT_TRANSPORT transport, int device_type);
181   bool CancelBond(const RawAddress& bd_addr);
182   bool RemoveBond(const RawAddress& bd_addr);
183 
184   uint16_t GetAclHandle(const RawAddress& remote_bda, tBT_TRANSPORT transport);
185 
186   void Register_HACK_SetScoDisconnectCallback(
187       HACK_ScoDisconnectCallback callback);
188 
189   static hci::AddressWithType GetAddressAndType(const RawAddress& bd_addr);
190 
191  private:
192   os::Alarm scanning_timer_;
193   os::Alarm observing_timer_;
194 
195   LegacyInquiryCompleteCallback legacy_inquiry_complete_callback_{};
196   uint8_t active_inquiry_mode_ = 0;
197 
198   class ReadRemoteName {
199    public:
200     ReadRemoteName() = default;
201     bool Start(RawAddress raw_address);
202     void Stop();
203     bool IsInProgress() const;
204     std::string AddressString() const;
205 
206    private:
207     std::mutex mutex_;
208     bool in_progress_ = false;
209     RawAddress raw_address_ = RawAddress::kEmpty;
210   };
211   ReadRemoteName le_read_remote_name_;
212   ReadRemoteName classic_read_remote_name_;
213 
214   class ScanningCallbacks : public hci::ScanningCallback {
215     void OnScannerRegistered(const bluetooth::hci::Uuid app_uuid,
216                              bluetooth::hci::ScannerId scanner_id,
217                              ScanningStatus status);
218     void OnScanResult(uint16_t event_type, uint8_t address_type,
219                       bluetooth::hci::Address address, uint8_t primary_phy,
220                       uint8_t secondary_phy, uint8_t advertising_sid,
221                       int8_t tx_power, int8_t rssi,
222                       uint16_t periodic_advertising_interval,
223                       std::vector<uint8_t> advertising_data);
224     void OnTrackAdvFoundLost(bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo
225                                  on_found_on_lost_info);
226     void OnBatchScanReports(int client_if, int status, int report_format,
227                             int num_records, std::vector<uint8_t> data);
228     void OnBatchScanThresholdCrossed(int client_if);
229     void OnTimeout();
230     void OnFilterEnable(bluetooth::hci::Enable enable, uint8_t status);
231     void OnFilterParamSetup(uint8_t available_spaces,
232                             bluetooth::hci::ApcfAction action, uint8_t status);
233     void OnFilterConfigCallback(bluetooth::hci::ApcfFilterType filter_type,
234                                 uint8_t available_spaces,
235                                 bluetooth::hci::ApcfAction action,
236                                 uint8_t status);
237   };
238   ScanningCallbacks scanning_callbacks_;
239 
240   // TODO(cmanton) abort if there is no classic acl link up
CheckClassicAclLink(const RawAddress & raw_address)241   bool CheckClassicAclLink(const RawAddress& raw_address) { return true; }
CheckLeAclLink(const RawAddress & raw_address)242   bool CheckLeAclLink(const RawAddress& raw_address) { return true; }
243   void StartScanning(bool use_active_scanning);
244 };
245 
246 }  // namespace shim
247 }  // namespace bluetooth
248