• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  Copyright 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 <string>
23 #include <unordered_map>
24 #include <unordered_set>
25 #include <vector>
26 
27 #include <base/macros.h>
28 #include <bluetooth/uuid.h>
29 
30 #include "service/bluetooth_instance.h"
31 #include "service/common/bluetooth/service.h"
32 #include "service/hal/bluetooth_gatt_interface.h"
33 
34 namespace bluetooth {
35 
36 // A GattServer instance represents an application's handle to perform GATT
37 // server-role operations. Instances cannot be created directly and should be
38 // obtained through the factory.
39 class GattServer : public BluetoothInstance,
40                    private hal::BluetoothGattInterface::ServerObserver {
41  public:
42   // Delegate interface is used to handle incoming requests and confirmations
43   // for a GATT service.
44   class Delegate {
45    public:
46     Delegate() = default;
47     virtual ~Delegate() = default;
48 
49     // Called when there is an incoming read request for the characteristic with
50     // ID |characteristic_id| from a remote device with address
51     // |device_address|. |request_id| can be used to respond to this request by
52     // calling SendResponse below.
53     virtual void OnCharacteristicReadRequest(GattServer* gatt_server,
54                                              const std::string& device_address,
55                                              int request_id, int offset,
56                                              bool is_long, uint16_t handle) = 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(GattServer* gatt_server,
63                                          const std::string& device_address,
64                                          int request_id, int offset,
65                                          bool is_long, uint16_t handle) = 0;
66 
67     // Called when there is an incoming write request for the characteristic
68     // with ID |characteristic_id| from a remote device with address
69     // |device_address|. |request_id| can be used to respond to this request by
70     // calling SendResponse, if the |need_response| parameter is true. Otherwise
71     // this is a "Write Without Reponse" procedure and SendResponse will fail.
72     // If |is_prepare_write| is true, then the write should not be committed
73     // immediately as this is a "Prepared Write Request". Instead, the Delegate
74     // should hold on to the value and either discard it or complete the write
75     // when it receives the OnExecuteWriteRequest event.
76     virtual void OnCharacteristicWriteRequest(
77         GattServer* gatt_server, const std::string& device_address,
78         int request_id, int offset, bool is_prepare_write, bool need_response,
79         const std::vector<uint8_t>& value, uint16_t handle) = 0;
80 
81     // Called when there is an incoming write request for the descriptor
82     // with ID |descriptor_id| from a remote device with address
83     // |device_address|. |request_id| can be used to respond to this request by
84     // calling SendResponse, if the |need_response| parameter is true. Otherwise
85     // this is a "Write Without Response" procedure and SendResponse will fail.
86     // If |is_prepare_write| is true, then the write should not be committed
87     // immediately as this is a "Prepared Write Request". Instead, the Delegate
88     // should hold on to the value and either discard it or complete the write
89     // when it receives the OnExecuteWriteRequest event.
90     virtual void OnDescriptorWriteRequest(
91         GattServer* gatt_server, const std::string& device_address,
92         int request_id, int offset, bool is_prepare_write, bool need_response,
93         const std::vector<uint8_t>& value, uint16_t handle) = 0;
94 
95     // Called when there is an incoming "Execute Write Request". If |is_execute|
96     // is true, then the Delegate should commit all previously prepared writes.
97     // Otherwise, all prepared writes should be aborted. The Delegate should
98     // call "SendResponse" to complete the procedure.
99     virtual void OnExecuteWriteRequest(GattServer* gatt_server,
100                                        const std::string& device_address,
101                                        int request_id, bool is_execute) = 0;
102 
103     virtual void OnConnectionStateChanged(GattServer* gatt_server,
104                                           const std::string& device_addres,
105                                           bool connected) = 0;
106 
107    private:
108     DISALLOW_COPY_AND_ASSIGN(Delegate);
109   };
110 
111   // The desctructor automatically unregisters this instance from the stack.
112   ~GattServer() override;
113 
114   // Assigns a delegate to this instance. |delegate| must out-live this
115   // GattServer instance.
116   void SetDelegate(Delegate* delegate);
117 
118   // BluetoothClientInstace overrides:
119   const Uuid& GetAppIdentifier() const override;
120   int GetInstanceId() const override;
121 
122   // Callback type used to report the status of an asynchronous GATT server
123   // operation.
124   using ResultCallback =
125       std::function<void(BLEStatus status, const Service& id)>;
126   using GattCallback = std::function<void(GATTError error)>;
127 
128   // Add service declaration. This method immediately
129   // returns false if a service hasn't been started. Otherwise, |callback| will
130   // be called asynchronously with the result of the operation.
131   //
132   // TODO(armansito): It is unclear to me what it means for this function to
133   // fail. What is the state that we're in? Is the service declaration over so
134   // we can add other services to this server instance? Do we need to clean up
135   // all the entries or does the upper-layer need to remove the service? Or are
136   // we in a stuck-state where the service declaration hasn't ended?
137   bool AddService(const Service&, const ResultCallback& callback);
138 
139   // Sends a response for a pending notification. |request_id| and
140   // |device_address| should match those that were received through one of the
141   // Delegate callbacks. |value| and |offset| are used for read requests and
142   // prepare write requests and should match the value of the attribute. Returns
143   // false if the pending request could not be resolved using the given
144   // parameters or if the call to the underlying stack fails.
145   bool SendResponse(const std::string& device_address, int request_id,
146                     GATTError error, int offset,
147                     const std::vector<uint8_t>& value);
148 
149   // Sends an ATT Handle-Value Notification to the device with BD_ADDR
150   // |device_address| for the characteristic with handle |handle| and
151   // value |value|. If |confirm| is true, then an ATT Handle-Value Indication
152   // will be sent instead, which requires the remote to confirm receipt. Returns
153   // false if there was an immediate error in initiating the notification
154   // procedure. Otherwise, returns true and reports the asynchronous result of
155   // the operation in |callback|.
156   //
157   // If |confirm| is true, then |callback| will be run when the remote device
158   // sends a ATT Handle-Value Confirmation packet. Otherwise, it will be run as
159   // soon as the notification has been sent out.
160   bool SendNotification(const std::string& device_address,
161                         const uint16_t handle, bool confirm,
162                         const std::vector<uint8_t>& value,
163                         const GattCallback& callback);
164 
165  private:
166   friend class GattServerFactory;
167 
168   // Used for the internal remote connection tracking. Keeps track of the
169   // request ID and the device address for the connection. If |request_id| is -1
170   // then no ATT read/write request is currently pending.
171   struct Connection {
ConnectionConnection172     Connection(int conn_id, const RawAddress& bdaddr)
173         : conn_id(conn_id), bdaddr(bdaddr) {}
ConnectionConnection174     Connection() : conn_id(-1) { memset(&bdaddr, 0, sizeof(bdaddr)); }
175 
176     int conn_id;
177     std::unordered_map<int, int> request_id_to_handle;
178     RawAddress bdaddr;
179   };
180 
181   // Used to keep track of a pending Handle-Value indication.
182   struct PendingIndication {
PendingIndicationPendingIndication183     explicit PendingIndication(const GattCallback& callback)
184         : has_success(false), callback(callback) {}
185 
186     bool has_success;
187     GattCallback callback;
188   };
189 
190   // Constructor shouldn't be called directly as instances are meant to be
191   // obtained from the factory.
192   GattServer(const Uuid& uuid, int server_id);
193 
194   // hal::BluetoothGattInterface::ServerObserver overrides:
195   void ConnectionCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
196                           int server_id, int connected,
197                           const RawAddress& bda) override;
198   void ServiceAddedCallback(hal::BluetoothGattInterface* gatt_iface, int status,
199                             int server_if,
200                             std::vector<btgatt_db_element_t>) override;
201   void ServiceStoppedCallback(hal::BluetoothGattInterface* gatt_iface,
202                               int status, int server_id,
203                               int service_handle) override;
204   void RequestReadCharacteristicCallback(
205       hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
206       const RawAddress& bda, int attribute_handle, int offset,
207       bool is_long) override;
208   void RequestReadDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
209                                      int conn_id, int trans_id,
210                                      const RawAddress& bda,
211                                      int attribute_handle, int offset,
212                                      bool is_long) override;
213   void RequestWriteCharacteristicCallback(
214       hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
215       const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
216       bool is_prep, std::vector<uint8_t> value) override;
217   void RequestWriteDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
218                                       int conn_id, int trans_id,
219                                       const RawAddress& bda, int attr_handle,
220                                       int offset, bool need_rsp, bool is_prep,
221                                       std::vector<uint8_t> value) override;
222   void RequestExecWriteCallback(hal::BluetoothGattInterface* gatt_iface,
223                                 int conn_id, int trans_id,
224                                 const RawAddress& bda, int exec_write) override;
225   void IndicationSentCallback(hal::BluetoothGattInterface* gatt_iface,
226                               int conn_id, int status) override;
227 
228   // Helper function that notifies and clears the pending callback.
229   void CleanUpPendingData();
230 
231   // Handles the next attribute entry in the pending service declaration.
232   void HandleNextEntry(hal::BluetoothGattInterface* gatt_iface);
233 
234   // Helper method that returns a pointer to an internal Connection instance
235   // that matches the given parameters.
236   std::shared_ptr<Connection> GetConnection(int conn_id, const RawAddress& bda,
237                                             int request_id);
238 
239   // See getters for documentation.
240   Uuid app_identifier_;
241   int server_id_;
242 
243   // Mutex that synchronizes access to the entries below.
244   std::mutex mutex_;
245   ResultCallback pending_end_decl_cb_;
246 
247   // GATT connection mappings from stack-provided "conn_id" IDs and remote
248   // device addresses to Connection structures. The conn_id map is one-to-one
249   // while the conn_addr map is one to many, as a remote device may support
250   // multiple transports (BR/EDR & LE) and use the same device address for both.
251   std::unordered_map<int, std::shared_ptr<Connection>> conn_id_map_;
252   std::unordered_map<std::string, std::vector<std::shared_ptr<Connection>>>
253       conn_addr_map_;
254 
255   // Connections for which a Handle-Value indication is pending. Since there can
256   // be multiple indications to the same device (in the case of a dual-mode
257   // device with simulatenous BR/EDR & LE GATT connections), we also keep track
258   // of whether there has been at least one successful confirmation.
259   std::unordered_map<int, std::shared_ptr<PendingIndication>>
260       pending_indications_;
261 
262   // Raw handle to the Delegate, which must outlive this GattServer instance.
263   Delegate* delegate_;
264 
265   DISALLOW_COPY_AND_ASSIGN(GattServer);
266 };
267 
268 // GattServerFactory is used to register and obtain a per-application GattServer
269 // instance. Users should call RegisterClient to obtain their own unique
270 // GattServer instance that has been registered with the Bluetooth stack.
271 class GattServerFactory : public BluetoothInstanceFactory,
272                           private hal::BluetoothGattInterface::ServerObserver {
273  public:
274   // Don't construct/destruct directly except in tests. Instead, obtain a handle
275   // from an Adapter instance.
276   GattServerFactory();
277   ~GattServerFactory() override;
278 
279   // BluetoothInstanceFactory override:
280   bool RegisterInstance(const Uuid& uuid,
281                         const RegisterCallback& callback) override;
282 
283  private:
284   // hal::BluetoothGattInterface::ServerObserver override:
285   void RegisterServerCallback(hal::BluetoothGattInterface* gatt_iface,
286                               int status, int server_id,
287                               const Uuid& app_uuid) override;
288 
289   // Map of pending calls to register.
290   std::mutex pending_calls_lock_;
291   std::unordered_map<Uuid, RegisterCallback> pending_calls_;
292 
293   DISALLOW_COPY_AND_ASSIGN(GattServerFactory);
294 };
295 
296 }  // namespace bluetooth
297