2 // Copyright (C) 2015 Google, Inc.
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:
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <unordered_map>
23 #include <unordered_set>
26 #include <base/macros.h>
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"
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.
38 class GattServer : public BluetoothInstance,
39 private hal::BluetoothGattInterface::ServerObserver {
41 // Delegate interface is used to handle incoming requests and confirmations
42 // for a GATT service.
46 virtual ~Delegate() = default;
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;
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;
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;
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;
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;
110 DISALLOW_COPY_AND_ASSIGN(Delegate);
113 // The desctructor automatically unregisters this instance from the stack.
114 ~GattServer() override;
116 // Assigns a delegate to this instance. |delegate| must out-live this
117 // GattServer instance.
118 void SetDelegate(Delegate* delegate);
120 // BluetoothClientInstace overrides:
121 const UUID& GetAppIdentifier() const override;
122 int GetInstanceId() const override;
124 // Callback type used to report the status of an asynchronous GATT server
126 using ResultCallback =
127 std::function<void(BLEStatus status, const GattIdentifier& id)>;
128 using GattCallback = std::function<void(GATTError error)>;
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.
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);
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);
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);
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.
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);
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);
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|.
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);
195 friend class GattServerFactory;
197 // Internal representation of an attribute entry as part of a service
199 struct AttributeEntry {
200 AttributeEntry(const GattIdentifier& id,
203 : id(id), char_properties(char_properties), permissions(permissions) {}
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) {}
216 GattIdentifier service_id;
218 std::deque<AttributeEntry> attributes;
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.
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));
232 std::unordered_map<int, int> request_id_to_handle;
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) {}
242 GattCallback callback;
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);
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,
253 std::unique_ptr<GattIdentifier> GetIdForCharacteristic(const UUID& uuid);
254 std::unique_ptr<GattIdentifier> GetIdForDescriptor(const UUID& uuid);
256 // hal::BluetoothGattInterface::ServerObserver overrides:
257 void ConnectionCallback(
258 hal::BluetoothGattInterface* gatt_iface,
259 int conn_id, int server_id,
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,
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,
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;
307 // Helper function that notifies and clears the pending callback.
308 void NotifyEndCallbackAndClearData(BLEStatus status,
309 const GattIdentifier& id);
310 void CleanUpPendingData();
312 // Handles the next attribute entry in the pending service declaration.
313 void HandleNextEntry(hal::BluetoothGattInterface* gatt_iface);
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,
320 // Pops the next GATT ID or entry from the pending service declaration's
322 std::unique_ptr<AttributeEntry> PopNextEntry();
323 std::unique_ptr<GattIdentifier> PopNextId();
325 // See getters for documentation.
326 UUID app_identifier_;
329 // Mutex that synchronizes access to the entries below.
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_;
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_;
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>>>
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_;
355 // Raw handle to the Delegate, which must outlive this GattServer instance.
358 DISALLOW_COPY_AND_ASSIGN(GattServer);
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.
364 class GattServerFactory : public BluetoothInstanceFactory,
365 private hal::BluetoothGattInterface::ServerObserver {
367 // Don't construct/destruct directly except in tests. Instead, obtain a handle
368 // from an Adapter instance.
370 ~GattServerFactory() override;
372 // BluetoothInstanceFactory override:
373 bool RegisterInstance(const UUID& uuid,
374 const RegisterCallback& callback) override;
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;
383 // Map of pending calls to register.
384 std::mutex pending_calls_lock_;
385 std::unordered_map<UUID, RegisterCallback> pending_calls_;
387 DISALLOW_COPY_AND_ASSIGN(GattServerFactory);
390 } // namespace bluetooth