1 //
2 //  Copyright (C) 2015 Google, Inc.
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 <atomic>
20 #include <functional>
21 #include <map>
22 #include <mutex>
23 
24 #include <base/macros.h>
25 
26 #include "service/bluetooth_instance.h"
27 #include "service/common/bluetooth/advertise_data.h"
28 #include "service/common/bluetooth/advertise_settings.h"
29 #include "service/common/bluetooth/low_energy_constants.h"
30 #include "service/common/bluetooth/scan_filter.h"
31 #include "service/common/bluetooth/scan_result.h"
32 #include "service/common/bluetooth/scan_settings.h"
33 #include "service/common/bluetooth/uuid.h"
34 #include "service/hal/bluetooth_gatt_interface.h"
35 
36 namespace bluetooth {
37 
38 struct ConnComparator {
operatorConnComparator39     bool operator()(const bt_bdaddr_t& a, const bt_bdaddr_t& b) const {
40         return memcmp(&a, &b, sizeof(bt_bdaddr_t)) < 0;
41     }
42 };
43 
44 class Adapter;
45 
46 // A LowEnergyClient represents an application's handle to perform various
47 // Bluetooth Low Energy GAP operations. Instances cannot be created directly and
48 // should be obtained through the factory.
49 class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
50                         public BluetoothInstance {
51  public:
52   // The Delegate interface is used to notify asynchronous events related to BLE
53   // GAP operations.
54   class Delegate {
55    public:
56     Delegate() = default;
57     virtual ~Delegate() = default;
58 
59     // Called asynchronously to notify the delegate of nearby BLE advertisers
60     // found during a device scan.
61     virtual void OnScanResult(LowEnergyClient* client,
62                               const ScanResult& scan_result) = 0;
63 
64     // Called asynchronously to notify the delegate of connection state change
65     virtual void OnConnectionState(LowEnergyClient* client, int status,
66                                    const char* address, bool connected) = 0;
67 
68     // Called asynchronously to notify the delegate of mtu change
69     virtual void OnMtuChanged(LowEnergyClient* client, int status, const char* address,
70                               int mtu) = 0;
71 
72    private:
73     DISALLOW_COPY_AND_ASSIGN(Delegate);
74   };
75 
76   // The destructor automatically unregisters this client instance from the
77   // stack.
78   ~LowEnergyClient() override;
79 
80   // Assigns a delegate to this instance. |delegate| must out-live this
81   // LowEnergyClient instance.
82   void SetDelegate(Delegate* delegate);
83 
84   // Callback type used to return the result of asynchronous operations below.
85   using StatusCallback = std::function<void(BLEStatus)>;
86 
87   // Initiates a BLE connection do device with address |address|. If
88   // |is_direct| is set, use direct connect procedure. Return true on success
89   //, false otherwise.
90   bool Connect(std::string address, bool is_direct);
91 
92   // Disconnect from previously connected BLE device with address |address|.
93   // Return true on success, false otherwise.
94   bool Disconnect(std::string address);
95 
96   // Sends request to set MTU to |mtu| for device with address |address|.
97   // Return true on success, false otherwise.
98   bool SetMtu(std::string address, int mtu);
99 
100   // Initiates a BLE device scan for this client using the given |settings| and
101   // |filters|. See the documentation for ScanSettings and ScanFilter for how
102   // these parameters can be configured. Return true on success, false
103   // otherwise. Please see logs for details in case of error.
104   bool StartScan(const ScanSettings& settings,
105                  const std::vector<ScanFilter>& filters);
106 
107   // Stops an ongoing BLE device scan for this client.
108   bool StopScan();
109 
110   // Starts advertising based on the given advertising and scan response
111   // data and the provided |settings|. Reports the result of the operation in
112   // |callback|. Return true on success, false otherwise. Please see logs for
113   // details in case of error.
114   bool StartAdvertising(const AdvertiseSettings& settings,
115                         const AdvertiseData& advertise_data,
116                         const AdvertiseData& scan_response,
117                         const StatusCallback& callback);
118 
119   // Stops advertising if it was already started. Reports the result of the
120   // operation in |callback|.
121   bool StopAdvertising(const StatusCallback& callback);
122 
123   // Returns true if advertising has been started.
124   bool IsAdvertisingStarted() const;
125 
126   // Returns the state of pending advertising operations.
127   bool IsStartingAdvertising() const;
128   bool IsStoppingAdvertising() const;
129 
130   // Returns the current advertising settings.
advertise_settings()131   const AdvertiseSettings& advertise_settings() const {
132     return advertise_settings_;
133   }
134 
135   // Returns the current scan settings.
scan_settings()136   const ScanSettings& scan_settings() const { return scan_settings_; }
137 
138   // BluetoothClientInstace overrides:
139   const UUID& GetAppIdentifier() const override;
140   int GetInstanceId() const override;
141 
142  private:
143   friend class LowEnergyClientFactory;
144 
145   // Constructor shouldn't be called directly as instances are meant to be
146   // obtained from the factory.
147   LowEnergyClient(Adapter& adapter, const UUID& uuid, int client_id);
148 
149   // BluetoothGattInterface::ClientObserver overrides:
150   void ScanResultCallback(
151       hal::BluetoothGattInterface* gatt_iface,
152       const bt_bdaddr_t& bda, int rssi, uint8_t* adv_data) override;
153 
154   void ConnectCallback(
155       hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
156       int client_id, const bt_bdaddr_t& bda) override;
157   void DisconnectCallback(
158       hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
159       int client_id, const bt_bdaddr_t& bda) override;
160   void MtuChangedCallback(
161       hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
162       int mtu) override;
163   void MultiAdvEnableCallback(
164       hal::BluetoothGattInterface* gatt_iface,
165       int client_id, int status) override;
166   void MultiAdvDataCallback(
167       hal::BluetoothGattInterface* gatt_iface,
168       int client_id, int status) override;
169   void MultiAdvDisableCallback(
170       hal::BluetoothGattInterface* gatt_iface,
171       int client_id, int status) override;
172 
173   // Helper method called from SetAdvertiseData/SetScanResponse.
174   bt_status_t SetAdvertiseData(
175       hal::BluetoothGattInterface* gatt_iface,
176       const AdvertiseData& data,
177       bool set_scan_rsp);
178 
179   // Handles deferred advertise/scan-response data updates. We set the data if
180   // there's data to be set, otherwise we either defer it if advertisements
181   // aren't enabled or do nothing.
182   void HandleDeferredAdvertiseData(hal::BluetoothGattInterface* gatt_iface);
183 
184   // Calls and clears the pending callbacks.
185   void InvokeAndClearStartCallback(BLEStatus status);
186   void InvokeAndClearStopCallback(BLEStatus status);
187 
188   // Raw pointer to the Bluetooth Adapter.
189   Adapter& adapter_;
190 
191   // See getters above for documentation.
192   UUID app_identifier_;
193   int client_id_;
194 
195   // Protects advertising-related members below.
196   std::mutex adv_fields_lock_;
197 
198   // The advertising and scan response data fields that will be sent to the
199   // controller.
200   AdvertiseData adv_data_;
201   AdvertiseData scan_response_;
202   std::atomic_bool adv_data_needs_update_;
203   std::atomic_bool scan_rsp_needs_update_;
204 
205   // Latest advertising settings.
206   AdvertiseSettings advertise_settings_;
207 
208   // Whether or not there is a pending call to update advertising or scan
209   // response data.
210   std::atomic_bool is_setting_adv_data_;
211 
212   std::atomic_bool adv_started_;
213   std::unique_ptr<StatusCallback> adv_start_callback_;
214   std::unique_ptr<StatusCallback> adv_stop_callback_;
215 
216   // Protects device scan related members below.
217   std::mutex scan_fields_lock_;
218 
219   // Current scan settings.
220   ScanSettings scan_settings_;
221 
222   // If true, then this client have a BLE device scan in progress.
223   std::atomic_bool scan_started_;
224 
225   // Raw handle to the Delegate, which must outlive this LowEnergyClient
226   // instance.
227   std::mutex delegate_mutex_;
228   Delegate* delegate_;
229 
230   // Protects device connection related members below.
231   std::mutex connection_fields_lock_;
232 
233   // Maps bluetooth address to connection id
234   //TODO(jpawlowski): change type to bimap
235   std::map<const bt_bdaddr_t, int, ConnComparator> connection_ids_;
236 
237   DISALLOW_COPY_AND_ASSIGN(LowEnergyClient);
238 };
239 
240 // LowEnergyClientFactory is used to register and obtain a per-application
241 // LowEnergyClient instance. Users should call RegisterInstance to obtain their
242 // own unique LowEnergyClient instance that has been registered with the
243 // Bluetooth stack.
244 class LowEnergyClientFactory
245     : private hal::BluetoothGattInterface::ClientObserver,
246       public BluetoothInstanceFactory {
247  public:
248   // Don't construct/destruct directly except in tests. Instead, obtain a handle
249   // from an Adapter instance.
250   LowEnergyClientFactory(Adapter& adapter);
251   ~LowEnergyClientFactory() override;
252 
253   // BluetoothInstanceFactory override:
254   bool RegisterInstance(const UUID& uuid,
255                         const RegisterCallback& callback) override;
256 
257  private:
258   friend class LowEnergyClient;
259 
260   // BluetoothGattInterface::ClientObserver overrides:
261   void RegisterClientCallback(
262       hal::BluetoothGattInterface* gatt_iface,
263       int status, int client_id,
264       const bt_uuid_t& app_uuid) override;
265 
266   // Map of pending calls to register.
267   std::mutex pending_calls_lock_;
268   std::map<UUID, RegisterCallback> pending_calls_;
269 
270   // Raw pointer to the Adapter that owns this factory.
271   Adapter& adapter_;
272 
273   DISALLOW_COPY_AND_ASSIGN(LowEnergyClientFactory);
274 };
275 
276 }  // namespace bluetooth
277