blob: ee3970b0f94dd0886578f5d82fbf6afa70af3660 [file] [log] [blame]
Ian Coolidge611fcf92015-06-03 17:20:30 -07001//
Jakub Pawlowski5b790fe2017-09-18 09:00:20 -07002// Copyright 2015 Google, Inc.
Ian Coolidge611fcf92015-06-03 17:20:30 -07003//
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//
Arman Uguray0f2d4892015-09-22 14:20:42 -070016
Ian Coolidge611fcf92015-06-03 17:20:30 -070017#pragma once
18
Arman Uguray91613742015-09-24 22:45:16 -070019#include <deque>
Arman Uguraydf0b2712015-09-23 17:25:54 -070020#include <functional>
Arman Uguray0f2d4892015-09-22 14:20:42 -070021#include <mutex>
Bailey Forrest03c278d2017-06-08 16:29:28 -070022#include <string>
Arman Uguraydf0b2712015-09-23 17:25:54 -070023#include <unordered_map>
Arman Uguray514bf602015-09-29 19:38:03 -070024#include <unordered_set>
25#include <vector>
Ian Coolidge611fcf92015-06-03 17:20:30 -070026
Arman Uguray0f2d4892015-09-22 14:20:42 -070027#include <base/macros.h>
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -070028#include <bluetooth/uuid.h>
Arman Uguray0f2d4892015-09-22 14:20:42 -070029
Arman Uguraybb18c412015-11-12 13:44:31 -080030#include "service/bluetooth_instance.h"
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -070031#include "service/common/bluetooth/service.h"
Arman Uguray0f2d4892015-09-22 14:20:42 -070032#include "service/hal/bluetooth_gatt_interface.h"
Ian Coolidge611fcf92015-06-03 17:20:30 -070033
34namespace bluetooth {
Ian Coolidge611fcf92015-06-03 17:20:30 -070035
Arman Uguray0f2d4892015-09-22 14:20:42 -070036// 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.
Arman Uguraybb18c412015-11-12 13:44:31 -080039class GattServer : public BluetoothInstance,
Arman Uguraydf0b2712015-09-23 17:25:54 -070040 private hal::BluetoothGattInterface::ServerObserver {
Ian Coolidge611fcf92015-06-03 17:20:30 -070041 public:
Arman Uguray514bf602015-09-29 19:38:03 -070042 // 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.
Myles Watson911d1ae2016-11-28 16:44:40 -080053 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;
Arman Uguray514bf602015-09-29 19:38:03 -070057
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.
Myles Watson911d1ae2016-11-28 16:44:40 -080062 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;
Arman Uguray514bf602015-09-29 19:38:03 -070066
Arman Uguray4ebcbd92015-09-29 22:09:46 -070067 // 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(
Myles Watson911d1ae2016-11-28 16:44:40 -080077 GattServer* gatt_server, const std::string& device_address,
Arman Uguray4ebcbd92015-09-29 22:09:46 -070078 int request_id, int offset, bool is_prepare_write, bool need_response,
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -070079 const std::vector<uint8_t>& value, uint16_t handle) = 0;
Arman Uguray4ebcbd92015-09-29 22:09:46 -070080
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(
Myles Watson911d1ae2016-11-28 16:44:40 -080091 GattServer* gatt_server, const std::string& device_address,
Arman Uguray4ebcbd92015-09-29 22:09:46 -070092 int request_id, int offset, bool is_prepare_write, bool need_response,
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -070093 const std::vector<uint8_t>& value, uint16_t handle) = 0;
Arman Uguray4ebcbd92015-09-29 22:09:46 -070094
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.
Myles Watson911d1ae2016-11-28 16:44:40 -080099 virtual void OnExecuteWriteRequest(GattServer* gatt_server,
100 const std::string& device_address,
101 int request_id, bool is_execute) = 0;
Arman Uguray4ebcbd92015-09-29 22:09:46 -0700102
Myles Watson911d1ae2016-11-28 16:44:40 -0800103 virtual void OnConnectionStateChanged(GattServer* gatt_server,
104 const std::string& device_addres,
105 bool connected) = 0;
Jakub Pawlowski79327272016-07-07 16:40:11 -0700106
Arman Uguray514bf602015-09-29 19:38:03 -0700107 private:
108 DISALLOW_COPY_AND_ASSIGN(Delegate);
109 };
110
Arman Uguray0f2d4892015-09-22 14:20:42 -0700111 // The desctructor automatically unregisters this instance from the stack.
112 ~GattServer() override;
Ian Coolidge611fcf92015-06-03 17:20:30 -0700113
Arman Uguray514bf602015-09-29 19:38:03 -0700114 // Assigns a delegate to this instance. |delegate| must out-live this
115 // GattServer instance.
116 void SetDelegate(Delegate* delegate);
117
Arman Uguray0f2d4892015-09-22 14:20:42 -0700118 // BluetoothClientInstace overrides:
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -0700119 const Uuid& GetAppIdentifier() const override;
Arman Uguraybb18c412015-11-12 13:44:31 -0800120 int GetInstanceId() const override;
Ian Coolidge611fcf92015-06-03 17:20:30 -0700121
Arman Uguraydf0b2712015-09-23 17:25:54 -0700122 // Callback type used to report the status of an asynchronous GATT server
123 // operation.
124 using ResultCallback =
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -0700125 std::function<void(BLEStatus status, const Service& id)>;
Arman Uguraycd644e32015-10-01 16:36:38 -0700126 using GattCallback = std::function<void(GATTError error)>;
Arman Uguraydf0b2712015-09-23 17:25:54 -0700127
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -0700128 // 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.
Arman Uguraydf0b2712015-09-23 17:25:54 -0700131 //
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?
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -0700137 bool AddService(const Service&, const ResultCallback& callback);
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -0700138
Arman Uguray514bf602015-09-29 19:38:03 -0700139 // 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
Arman Uguraycd644e32015-10-01 16:36:38 -0700149 // Sends an ATT Handle-Value Notification to the device with BD_ADDR
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -0700150 // |device_address| for the characteristic with handle |handle| and
Arman Uguraycd644e32015-10-01 16:36:38 -0700151 // 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,
Myles Watson911d1ae2016-11-28 16:44:40 -0800161 const uint16_t handle, bool confirm,
162 const std::vector<uint8_t>& value,
Arman Uguraycd644e32015-10-01 16:36:38 -0700163 const GattCallback& callback);
164
Ian Coolidge611fcf92015-06-03 17:20:30 -0700165 private:
Arman Uguray0f2d4892015-09-22 14:20:42 -0700166 friend class GattServerFactory;
167
Arman Uguray514bf602015-09-29 19:38:03 -0700168 // 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 {
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700172 Connection(int conn_id, const RawAddress& bdaddr)
Arman Uguray514bf602015-09-29 19:38:03 -0700173 : conn_id(conn_id), bdaddr(bdaddr) {}
Myles Watson911d1ae2016-11-28 16:44:40 -0800174 Connection() : conn_id(-1) { memset(&bdaddr, 0, sizeof(bdaddr)); }
Arman Uguray514bf602015-09-29 19:38:03 -0700175
176 int conn_id;
177 std::unordered_map<int, int> request_id_to_handle;
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700178 RawAddress bdaddr;
Arman Uguray514bf602015-09-29 19:38:03 -0700179 };
180
Arman Uguraycd644e32015-10-01 16:36:38 -0700181 // Used to keep track of a pending Handle-Value indication.
182 struct PendingIndication {
Chih-Hung Hsieh33987302016-06-30 15:45:24 -0700183 explicit PendingIndication(const GattCallback& callback)
Arman Uguraycd644e32015-10-01 16:36:38 -0700184 : has_success(false), callback(callback) {}
185
186 bool has_success;
187 GattCallback callback;
188 };
189
Arman Uguray50a31542015-11-10 18:03:36 -0800190 // Constructor shouldn't be called directly as instances are meant to be
Arman Uguray0f2d4892015-09-22 14:20:42 -0700191 // obtained from the factory.
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -0700192 GattServer(const Uuid& uuid, int server_id);
Arman Uguray0f2d4892015-09-22 14:20:42 -0700193
Arman Uguraydf0b2712015-09-23 17:25:54 -0700194 // hal::BluetoothGattInterface::ServerObserver overrides:
Myles Watson911d1ae2016-11-28 16:44:40 -0800195 void ConnectionCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
196 int server_id, int connected,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700197 const RawAddress& bda) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800198 void ServiceAddedCallback(hal::BluetoothGattInterface* gatt_iface, int status,
199 int server_if,
Pavlin Radoslavovb324a8d2016-12-09 17:50:59 -0800200 std::vector<btgatt_db_element_t>) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800201 void ServiceStoppedCallback(hal::BluetoothGattInterface* gatt_iface,
202 int status, int server_id,
203 int service_handle) override;
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -0700204 void RequestReadCharacteristicCallback(
Myles Watson911d1ae2016-11-28 16:44:40 -0800205 hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700206 const RawAddress& bda, int attribute_handle, int offset,
Arman Uguray514bf602015-09-29 19:38:03 -0700207 bool is_long) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800208 void RequestReadDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
209 int conn_id, int trans_id,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700210 const RawAddress& bda,
Myles Watson911d1ae2016-11-28 16:44:40 -0800211 int attribute_handle, int offset,
212 bool is_long) override;
Jakub Pawlowskia641b6f2016-03-26 00:47:23 -0700213 void RequestWriteCharacteristicCallback(
Myles Watson911d1ae2016-11-28 16:44:40 -0800214 hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700215 const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
Pavlin Radoslavovb324a8d2016-12-09 17:50:59 -0800216 bool is_prep, std::vector<uint8_t> value) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800217 void RequestWriteDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
218 int conn_id, int trans_id,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700219 const RawAddress& bda, int attr_handle,
Myles Watson911d1ae2016-11-28 16:44:40 -0800220 int offset, bool need_rsp, bool is_prep,
Pavlin Radoslavovb324a8d2016-12-09 17:50:59 -0800221 std::vector<uint8_t> value) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800222 void RequestExecWriteCallback(hal::BluetoothGattInterface* gatt_iface,
223 int conn_id, int trans_id,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700224 const RawAddress& bda, int exec_write) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800225 void IndicationSentCallback(hal::BluetoothGattInterface* gatt_iface,
226 int conn_id, int status) override;
Arman Uguraydf0b2712015-09-23 17:25:54 -0700227
228 // Helper function that notifies and clears the pending callback.
Arman Uguraydf0b2712015-09-23 17:25:54 -0700229 void CleanUpPendingData();
230
Arman Uguray91613742015-09-24 22:45:16 -0700231 // Handles the next attribute entry in the pending service declaration.
232 void HandleNextEntry(hal::BluetoothGattInterface* gatt_iface);
233
Arman Uguray514bf602015-09-29 19:38:03 -0700234 // Helper method that returns a pointer to an internal Connection instance
235 // that matches the given parameters.
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700236 std::shared_ptr<Connection> GetConnection(int conn_id, const RawAddress& bda,
Arman Uguray514bf602015-09-29 19:38:03 -0700237 int request_id);
238
Arman Uguray0f2d4892015-09-22 14:20:42 -0700239 // See getters for documentation.
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -0700240 Uuid app_identifier_;
Arman Uguraybb18c412015-11-12 13:44:31 -0800241 int server_id_;
Arman Uguray0f2d4892015-09-22 14:20:42 -0700242
Arman Uguraydf0b2712015-09-23 17:25:54 -0700243 // Mutex that synchronizes access to the entries below.
244 std::mutex mutex_;
Arman Uguraydf0b2712015-09-23 17:25:54 -0700245 ResultCallback pending_end_decl_cb_;
Arman Uguray514bf602015-09-29 19:38:03 -0700246
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
Arman Uguraycd644e32015-10-01 16:36:38 -0700255 // 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
Arman Uguray514bf602015-09-29 19:38:03 -0700262 // Raw handle to the Delegate, which must outlive this GattServer instance.
263 Delegate* delegate_;
Arman Uguraydf0b2712015-09-23 17:25:54 -0700264
Arman Uguray0f2d4892015-09-22 14:20:42 -0700265 DISALLOW_COPY_AND_ASSIGN(GattServer);
Ian Coolidge611fcf92015-06-03 17:20:30 -0700266};
267
Arman Uguray0f2d4892015-09-22 14:20:42 -0700268// GattServerFactory is used to register and obtain a per-application GattServer
Arman Uguray50a31542015-11-10 18:03:36 -0800269// instance. Users should call RegisterClient to obtain their own unique
Arman Uguray0f2d4892015-09-22 14:20:42 -0700270// GattServer instance that has been registered with the Bluetooth stack.
Arman Uguraybb18c412015-11-12 13:44:31 -0800271class GattServerFactory : public BluetoothInstanceFactory,
Arman Uguray0f2d4892015-09-22 14:20:42 -0700272 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
Arman Uguraybb18c412015-11-12 13:44:31 -0800279 // BluetoothInstanceFactory override:
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -0700280 bool RegisterInstance(const Uuid& uuid,
Arman Uguraybb18c412015-11-12 13:44:31 -0800281 const RegisterCallback& callback) override;
Arman Uguray0f2d4892015-09-22 14:20:42 -0700282
283 private:
284 // hal::BluetoothGattInterface::ServerObserver override:
Myles Watson911d1ae2016-11-28 16:44:40 -0800285 void RegisterServerCallback(hal::BluetoothGattInterface* gatt_iface,
286 int status, int server_id,
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -0700287 const Uuid& app_uuid) override;
Arman Uguray0f2d4892015-09-22 14:20:42 -0700288
289 // Map of pending calls to register.
290 std::mutex pending_calls_lock_;
Jakub Pawlowski819e2ec2017-07-10 09:56:09 -0700291 std::unordered_map<Uuid, RegisterCallback> pending_calls_;
Arman Uguray0f2d4892015-09-22 14:20:42 -0700292
293 DISALLOW_COPY_AND_ASSIGN(GattServerFactory);
294};
295
Ian Coolidge611fcf92015-06-03 17:20:30 -0700296} // namespace bluetooth