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 <deque>
20#include <functional>
21#include <mutex>
22#include <unordered_map>
23#include <unordered_set>
24#include <vector>
25
26#include <base/macros.h>
27
28#include "service/bluetooth_instance.h"
29#include "service/common/bluetooth/gatt_identifier.h"
30#include "service/common/bluetooth/uuid.h"
31#include "service/hal/bluetooth_gatt_interface.h"
32
33namespace bluetooth {
34
35// A GattServer instance represents an application's handle to perform GATT
36// server-role operations. Instances cannot be created directly and should be
37// obtained through the factory.
38class GattServer : public BluetoothInstance,
39                   private hal::BluetoothGattInterface::ServerObserver {
40 public:
41  // Delegate interface is used to handle incoming requests and confirmations
42  // for a GATT service.
43  class Delegate {
44   public:
45    Delegate() = default;
46    virtual ~Delegate() = default;
47
48    // Called when there is an incoming read request for the characteristic with
49    // ID |characteristic_id| from a remote device with address
50    // |device_address|. |request_id| can be used to respond to this request by
51    // calling SendResponse below.
52    virtual void OnCharacteristicReadRequest(
53        GattServer* gatt_server,
54        const std::string& device_address,
55        int request_id, int offset, bool is_long,
56        const bluetooth::GattIdentifier& characteristic_id) = 0;
57
58    // Called when there is an incoming read request for the descriptor with
59    // ID |descriptor_id| from a remote device with address |device_address|.
60    // |request_id| can be used to respond to this request by
61    // calling SendResponse below.
62    virtual void OnDescriptorReadRequest(
63        GattServer* gatt_server,
64        const std::string& device_address,
65        int request_id, int offset, bool is_long,
66        const bluetooth::GattIdentifier& descriptor_id) = 0;
67
68    // Called when there is an incoming write request for the characteristic
69    // with ID |characteristic_id| from a remote device with address
70    // |device_address|. |request_id| can be used to respond to this request by
71    // calling SendResponse, if the |need_response| parameter is true. Otherwise
72    // this is a "Write Without Reponse" procedure and SendResponse will fail.
73    // If |is_prepare_write| is true, then the write should not be committed
74    // immediately as this is a "Prepared Write Request". Instead, the Delegate
75    // should hold on to the value and either discard it or complete the write
76    // when it receives the OnExecuteWriteRequest event.
77    virtual void OnCharacteristicWriteRequest(
78        GattServer* gatt_server,
79        const std::string& device_address,
80        int request_id, int offset, bool is_prepare_write, bool need_response,
81        const std::vector<uint8_t>& value,
82        const bluetooth::GattIdentifier& characteristic_id) = 0;
83
84    // Called when there is an incoming write request for the descriptor
85    // with ID |descriptor_id| from a remote device with address
86    // |device_address|. |request_id| can be used to respond to this request by
87    // calling SendResponse, if the |need_response| parameter is true. Otherwise
88    // this is a "Write Without Response" procedure and SendResponse will fail.
89    // If |is_prepare_write| is true, then the write should not be committed
90    // immediately as this is a "Prepared Write Request". Instead, the Delegate
91    // should hold on to the value and either discard it or complete the write
92    // when it receives the OnExecuteWriteRequest event.
93    virtual void OnDescriptorWriteRequest(
94        GattServer* gatt_server,
95        const std::string& device_address,
96        int request_id, int offset, bool is_prepare_write, bool need_response,
97        const std::vector<uint8_t>& value,
98        const bluetooth::GattIdentifier& descriptor_id) = 0;
99
100    // Called when there is an incoming "Execute Write Request". If |is_execute|
101    // is true, then the Delegate should commit all previously prepared writes.
102    // Otherwise, all prepared writes should be aborted. The Delegate should
103    // call "SendResponse" to complete the procedure.
104    virtual void OnExecuteWriteRequest(
105        GattServer* gatt_server,
106        const std::string& device_address,
107        int request_id, bool is_execute) = 0;
108
109   private:
110    DISALLOW_COPY_AND_ASSIGN(Delegate);
111  };
112
113  // The desctructor automatically unregisters this instance from the stack.
114  ~GattServer() override;
115
116  // Assigns a delegate to this instance. |delegate| must out-live this
117  // GattServer instance.
118  void SetDelegate(Delegate* delegate);
119
120  // BluetoothClientInstace overrides:
121  const UUID& GetAppIdentifier() const override;
122  int GetInstanceId() const override;
123
124  // Callback type used to report the status of an asynchronous GATT server
125  // operation.
126  using ResultCallback =
127      std::function<void(BLEStatus status, const GattIdentifier& id)>;
128  using GattCallback = std::function<void(GATTError error)>;
129
130  // Starts a new GATT service declaration for the service with the given
131  // parameters. In the case of an error, for example If a service declaration
132  // is already in progress, then this method returns a NULL pointer. Otherwise,
133  // this returns an identifier that uniquely identifies the added service.
134  //
135  // TODO(armansito): In the framework code, the "min_handles" parameter is
136  // annotated to be used for "conformance testing only". I don't fully see the
137  // point of this and suggest getting rid of this parameter entirely. For now
138  // this code doesn't declare or use it.
139  std::unique_ptr<GattIdentifier> BeginServiceDeclaration(
140      const UUID& uuid, bool is_primary);
141
142  // Inserts a new characteristic definition into a previously begun service
143  // declaration. Returns the assigned identifier for the characteristic, or
144  // nullptr if a service declaration wasn't begun or a call to
145  // EndServiceDeclaration is still in progress.
146  std::unique_ptr<GattIdentifier> AddCharacteristic(
147      const UUID& uuid, int properties, int permissions);
148
149  // Inserts a new descriptor definition into a previous begun service
150  // declaration. Returns the assigned identifier for the descriptor, or
151  // nullptr if a service declaration wasn't begun, a call to
152  // EndServiceDeclaration is still in progress, or a characteristic definition
153  // doesn't properly precede this definition.
154  std::unique_ptr<GattIdentifier> AddDescriptor(
155      const UUID& uuid, int permissions);
156
157  // Ends a previously started service declaration. This method immediately
158  // returns false if a service declaration hasn't been started. Otherwise,
159  // |callback| will be called asynchronously with the result of the operation.
160  //
161  // TODO(armansito): It is unclear to me what it means for this function to
162  // fail. What is the state that we're in? Is the service declaration over so
163  // we can add other services to this server instance? Do we need to clean up
164  // all the entries or does the upper-layer need to remove the service? Or are
165  // we in a stuck-state where the service declaration hasn't ended?
166  bool EndServiceDeclaration(const ResultCallback& callback);
167
168  // Sends a response for a pending notification. |request_id| and
169  // |device_address| should match those that were received through one of the
170  // Delegate callbacks. |value| and |offset| are used for read requests and
171  // prepare write requests and should match the value of the attribute. Returns
172  // false if the pending request could not be resolved using the given
173  // parameters or if the call to the underlying stack fails.
174  bool SendResponse(const std::string& device_address, int request_id,
175                    GATTError error, int offset,
176                    const std::vector<uint8_t>& value);
177
178  // Sends an ATT Handle-Value Notification to the device with BD_ADDR
179  // |device_address| for the characteristic with ID |characteristic_id| and
180  // value |value|. If |confirm| is true, then an ATT Handle-Value Indication
181  // will be sent instead, which requires the remote to confirm receipt. Returns
182  // false if there was an immediate error in initiating the notification
183  // procedure. Otherwise, returns true and reports the asynchronous result of
184  // the operation in |callback|.
185  //
186  // If |confirm| is true, then |callback| will be run when the remote device
187  // sends a ATT Handle-Value Confirmation packet. Otherwise, it will be run as
188  // soon as the notification has been sent out.
189  bool SendNotification(const std::string& device_address,
190                        const GattIdentifier& characteristic_id,
191                        bool confirm, const std::vector<uint8_t>& value,
192                        const GattCallback& callback);
193
194 private:
195  friend class GattServerFactory;
196
197  // Internal representation of an attribute entry as part of a service
198  // declaration.
199  struct AttributeEntry {
200    AttributeEntry(const GattIdentifier& id,
201                   int char_properties,
202                   int permissions)
203        : id(id), char_properties(char_properties), permissions(permissions) {}
204
205    GattIdentifier id;
206    int char_properties;
207    int permissions;
208  };
209
210  // Internal representation of a GATT service declaration before it has been
211  // sent to the stack.
212  struct ServiceDeclaration {
213    ServiceDeclaration() : num_handles(0), service_handle(-1) {}
214
215    size_t num_handles;
216    GattIdentifier service_id;
217    int service_handle;
218    std::deque<AttributeEntry> attributes;
219  };
220
221  // Used for the internal remote connection tracking. Keeps track of the
222  // request ID and the device address for the connection. If |request_id| is -1
223  // then no ATT read/write request is currently pending.
224  struct Connection {
225    Connection(int conn_id, const bt_bdaddr_t& bdaddr)
226        : conn_id(conn_id), bdaddr(bdaddr) {}
227    Connection() : conn_id(-1) {
228      memset(&bdaddr, 0, sizeof(bdaddr));
229    }
230
231    int conn_id;
232    std::unordered_map<int, int> request_id_to_handle;
233    bt_bdaddr_t bdaddr;
234  };
235
236  // Used to keep track of a pending Handle-Value indication.
237  struct PendingIndication {
238    PendingIndication(const GattCallback& callback)
239        : has_success(false), callback(callback) {}
240
241    bool has_success;
242    GattCallback callback;
243  };
244
245  // Constructor shouldn't be called directly as instances are meant to be
246  // obtained from the factory.
247  GattServer(const UUID& uuid, int server_id);
248
249  // Returns a GattIdentifier for the attribute with the given UUID within the
250  // current pending service declaration.
251  std::unique_ptr<GattIdentifier> GetIdForService(const UUID& uuid,
252                                                  bool is_primary);
253  std::unique_ptr<GattIdentifier> GetIdForCharacteristic(const UUID& uuid);
254  std::unique_ptr<GattIdentifier> GetIdForDescriptor(const UUID& uuid);
255
256  // hal::BluetoothGattInterface::ServerObserver overrides:
257  void ConnectionCallback(
258      hal::BluetoothGattInterface* gatt_iface,
259      int conn_id, int server_id,
260      int connected,
261      const bt_bdaddr_t& bda) override;
262  void ServiceAddedCallback(
263      hal::BluetoothGattInterface* gatt_iface,
264      int status, int server_id,
265      const btgatt_srvc_id_t& srvc_id,
266      int service_handle) override;
267  void CharacteristicAddedCallback(
268      hal::BluetoothGattInterface* gatt_iface,
269      int status, int server_id,
270      const bt_uuid_t& uuid,
271      int service_handle,
272      int char_handle) override;
273  void DescriptorAddedCallback(
274      hal::BluetoothGattInterface* gatt_iface,
275      int status, int server_id,
276      const bt_uuid_t& uuid,
277      int service_handle,
278      int desc_handle) override;
279  void ServiceStartedCallback(
280      hal::BluetoothGattInterface* gatt_iface,
281      int status, int server_id,
282      int service_handle) override;
283  void ServiceStoppedCallback(
284      hal::BluetoothGattInterface* gatt_iface,
285      int status, int server_id,
286      int service_handle) override;
287  void RequestReadCallback(
288      hal::BluetoothGattInterface* gatt_iface,
289      int conn_id, int trans_id,
290      const bt_bdaddr_t& bda,
291      int attribute_handle, int offset,
292      bool is_long) override;
293  void RequestWriteCallback(
294      hal::BluetoothGattInterface* gatt_iface,
295      int conn_id, int trans_id,
296      const bt_bdaddr_t& bda,
297      int attr_handle, int offset, int length,
298      bool need_rsp, bool is_prep, uint8_t* value) override;
299  void RequestExecWriteCallback(
300      hal::BluetoothGattInterface* gatt_iface,
301      int conn_id, int trans_id,
302      const bt_bdaddr_t& bda, int exec_write) override;
303  void IndicationSentCallback(
304      hal::BluetoothGattInterface* gatt_iface,
305      int conn_id, int status) override;
306
307  // Helper function that notifies and clears the pending callback.
308  void NotifyEndCallbackAndClearData(BLEStatus status,
309                                     const GattIdentifier& id);
310  void CleanUpPendingData();
311
312  // Handles the next attribute entry in the pending service declaration.
313  void HandleNextEntry(hal::BluetoothGattInterface* gatt_iface);
314
315  // Helper method that returns a pointer to an internal Connection instance
316  // that matches the given parameters.
317  std::shared_ptr<Connection> GetConnection(int conn_id, const bt_bdaddr_t& bda,
318                                            int request_id);
319
320  // Pops the next GATT ID or entry from the pending service declaration's
321  // attribute list.
322  std::unique_ptr<AttributeEntry> PopNextEntry();
323  std::unique_ptr<GattIdentifier> PopNextId();
324
325  // See getters for documentation.
326  UUID app_identifier_;
327  int server_id_;
328
329  // Mutex that synchronizes access to the entries below.
330  std::mutex mutex_;
331  std::unique_ptr<GattIdentifier> pending_id_;
332  std::unique_ptr<ServiceDeclaration> pending_decl_;
333  ResultCallback pending_end_decl_cb_;
334  std::unordered_map<GattIdentifier, int> pending_handle_map_;
335
336  // Mapping of handles and GATT identifiers for started services.
337  std::unordered_map<GattIdentifier, int> id_to_handle_map_;
338  std::unordered_map<int, GattIdentifier> handle_to_id_map_;
339
340  // GATT connection mappings from stack-provided "conn_id" IDs and remote
341  // device addresses to Connection structures. The conn_id map is one-to-one
342  // while the conn_addr map is one to many, as a remote device may support
343  // multiple transports (BR/EDR & LE) and use the same device address for both.
344  std::unordered_map<int, std::shared_ptr<Connection>> conn_id_map_;
345  std::unordered_map<std::string, std::vector<std::shared_ptr<Connection>>>
346      conn_addr_map_;
347
348  // Connections for which a Handle-Value indication is pending. Since there can
349  // be multiple indications to the same device (in the case of a dual-mode
350  // device with simulatenous BR/EDR & LE GATT connections), we also keep track
351  // of whether there has been at least one successful confirmation.
352  std::unordered_map<int, std::shared_ptr<PendingIndication>>
353      pending_indications_;
354
355  // Raw handle to the Delegate, which must outlive this GattServer instance.
356  Delegate* delegate_;
357
358  DISALLOW_COPY_AND_ASSIGN(GattServer);
359};
360
361// GattServerFactory is used to register and obtain a per-application GattServer
362// instance. Users should call RegisterClient to obtain their own unique
363// GattServer instance that has been registered with the Bluetooth stack.
364class GattServerFactory : public BluetoothInstanceFactory,
365                          private hal::BluetoothGattInterface::ServerObserver {
366 public:
367  // Don't construct/destruct directly except in tests. Instead, obtain a handle
368  // from an Adapter instance.
369  GattServerFactory();
370  ~GattServerFactory() override;
371
372  // BluetoothInstanceFactory override:
373  bool RegisterInstance(const UUID& uuid,
374                        const RegisterCallback& callback) override;
375
376 private:
377  // hal::BluetoothGattInterface::ServerObserver override:
378  void RegisterServerCallback(
379      hal::BluetoothGattInterface* gatt_iface,
380      int status, int server_id,
381      const bt_uuid_t& app_uuid) override;
382
383  // Map of pending calls to register.
384  std::mutex pending_calls_lock_;
385  std::unordered_map<UUID, RegisterCallback> pending_calls_;
386
387  DISALLOW_COPY_AND_ASSIGN(GattServerFactory);
388};
389
390}  // namespace bluetooth
391