Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 1 | // |
Jakub Pawlowski | 5b790fe | 2017-09-18 09:00:20 -0700 | [diff] [blame] | 2 | // Copyright 2015 Google, Inc. |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 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 | // |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 16 | |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 17 | #pragma once |
| 18 | |
Arman Uguray | 9161374 | 2015-09-24 22:45:16 -0700 | [diff] [blame] | 19 | #include <deque> |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 20 | #include <functional> |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 21 | #include <mutex> |
Bailey Forrest | 03c278d | 2017-06-08 16:29:28 -0700 | [diff] [blame] | 22 | #include <string> |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 23 | #include <unordered_map> |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 24 | #include <unordered_set> |
| 25 | #include <vector> |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 26 | |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 27 | #include <base/macros.h> |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 28 | #include <bluetooth/uuid.h> |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 29 | |
Arman Uguray | bb18c41 | 2015-11-12 13:44:31 -0800 | [diff] [blame] | 30 | #include "service/bluetooth_instance.h" |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 31 | #include "service/common/bluetooth/service.h" |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 32 | #include "service/hal/bluetooth_gatt_interface.h" |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 33 | |
| 34 | namespace bluetooth { |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 35 | |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 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. |
Arman Uguray | bb18c41 | 2015-11-12 13:44:31 -0800 | [diff] [blame] | 39 | class GattServer : public BluetoothInstance, |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 40 | private hal::BluetoothGattInterface::ServerObserver { |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 41 | public: |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 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. |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 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; |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 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. |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 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; |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 66 | |
Arman Uguray | 4ebcbd9 | 2015-09-29 22:09:46 -0700 | [diff] [blame] | 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( |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 77 | GattServer* gatt_server, const std::string& device_address, |
Arman Uguray | 4ebcbd9 | 2015-09-29 22:09:46 -0700 | [diff] [blame] | 78 | int request_id, int offset, bool is_prepare_write, bool need_response, |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 79 | const std::vector<uint8_t>& value, uint16_t handle) = 0; |
Arman Uguray | 4ebcbd9 | 2015-09-29 22:09:46 -0700 | [diff] [blame] | 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( |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 91 | GattServer* gatt_server, const std::string& device_address, |
Arman Uguray | 4ebcbd9 | 2015-09-29 22:09:46 -0700 | [diff] [blame] | 92 | int request_id, int offset, bool is_prepare_write, bool need_response, |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 93 | const std::vector<uint8_t>& value, uint16_t handle) = 0; |
Arman Uguray | 4ebcbd9 | 2015-09-29 22:09:46 -0700 | [diff] [blame] | 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. |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 99 | virtual void OnExecuteWriteRequest(GattServer* gatt_server, |
| 100 | const std::string& device_address, |
| 101 | int request_id, bool is_execute) = 0; |
Arman Uguray | 4ebcbd9 | 2015-09-29 22:09:46 -0700 | [diff] [blame] | 102 | |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 103 | virtual void OnConnectionStateChanged(GattServer* gatt_server, |
| 104 | const std::string& device_addres, |
| 105 | bool connected) = 0; |
Jakub Pawlowski | 7932727 | 2016-07-07 16:40:11 -0700 | [diff] [blame] | 106 | |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 107 | private: |
| 108 | DISALLOW_COPY_AND_ASSIGN(Delegate); |
| 109 | }; |
| 110 | |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 111 | // The desctructor automatically unregisters this instance from the stack. |
| 112 | ~GattServer() override; |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 113 | |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 114 | // Assigns a delegate to this instance. |delegate| must out-live this |
| 115 | // GattServer instance. |
| 116 | void SetDelegate(Delegate* delegate); |
| 117 | |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 118 | // BluetoothClientInstace overrides: |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 119 | const Uuid& GetAppIdentifier() const override; |
Arman Uguray | bb18c41 | 2015-11-12 13:44:31 -0800 | [diff] [blame] | 120 | int GetInstanceId() const override; |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 121 | |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 122 | // Callback type used to report the status of an asynchronous GATT server |
| 123 | // operation. |
| 124 | using ResultCallback = |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 125 | std::function<void(BLEStatus status, const Service& id)>; |
Arman Uguray | cd644e3 | 2015-10-01 16:36:38 -0700 | [diff] [blame] | 126 | using GattCallback = std::function<void(GATTError error)>; |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 127 | |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 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. |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 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? |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 137 | bool AddService(const Service&, const ResultCallback& callback); |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 138 | |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 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 | |
Arman Uguray | cd644e3 | 2015-10-01 16:36:38 -0700 | [diff] [blame] | 149 | // Sends an ATT Handle-Value Notification to the device with BD_ADDR |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 150 | // |device_address| for the characteristic with handle |handle| and |
Arman Uguray | cd644e3 | 2015-10-01 16:36:38 -0700 | [diff] [blame] | 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, |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 161 | const uint16_t handle, bool confirm, |
| 162 | const std::vector<uint8_t>& value, |
Arman Uguray | cd644e3 | 2015-10-01 16:36:38 -0700 | [diff] [blame] | 163 | const GattCallback& callback); |
| 164 | |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 165 | private: |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 166 | friend class GattServerFactory; |
| 167 | |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 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 { |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 172 | Connection(int conn_id, const RawAddress& bdaddr) |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 173 | : conn_id(conn_id), bdaddr(bdaddr) {} |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 174 | Connection() : conn_id(-1) { memset(&bdaddr, 0, sizeof(bdaddr)); } |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 175 | |
| 176 | int conn_id; |
| 177 | std::unordered_map<int, int> request_id_to_handle; |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 178 | RawAddress bdaddr; |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 179 | }; |
| 180 | |
Arman Uguray | cd644e3 | 2015-10-01 16:36:38 -0700 | [diff] [blame] | 181 | // Used to keep track of a pending Handle-Value indication. |
| 182 | struct PendingIndication { |
Chih-Hung Hsieh | 3398730 | 2016-06-30 15:45:24 -0700 | [diff] [blame] | 183 | explicit PendingIndication(const GattCallback& callback) |
Arman Uguray | cd644e3 | 2015-10-01 16:36:38 -0700 | [diff] [blame] | 184 | : has_success(false), callback(callback) {} |
| 185 | |
| 186 | bool has_success; |
| 187 | GattCallback callback; |
| 188 | }; |
| 189 | |
Arman Uguray | 50a3154 | 2015-11-10 18:03:36 -0800 | [diff] [blame] | 190 | // Constructor shouldn't be called directly as instances are meant to be |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 191 | // obtained from the factory. |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 192 | GattServer(const Uuid& uuid, int server_id); |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 193 | |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 194 | // hal::BluetoothGattInterface::ServerObserver overrides: |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 195 | void ConnectionCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id, |
| 196 | int server_id, int connected, |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 197 | const RawAddress& bda) override; |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 198 | void ServiceAddedCallback(hal::BluetoothGattInterface* gatt_iface, int status, |
| 199 | int server_if, |
Pavlin Radoslavov | b324a8d | 2016-12-09 17:50:59 -0800 | [diff] [blame] | 200 | std::vector<btgatt_db_element_t>) override; |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 201 | void ServiceStoppedCallback(hal::BluetoothGattInterface* gatt_iface, |
| 202 | int status, int server_id, |
| 203 | int service_handle) override; |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 204 | void RequestReadCharacteristicCallback( |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 205 | hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id, |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 206 | const RawAddress& bda, int attribute_handle, int offset, |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 207 | bool is_long) override; |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 208 | void RequestReadDescriptorCallback(hal::BluetoothGattInterface* gatt_iface, |
| 209 | int conn_id, int trans_id, |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 210 | const RawAddress& bda, |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 211 | int attribute_handle, int offset, |
| 212 | bool is_long) override; |
Jakub Pawlowski | a641b6f | 2016-03-26 00:47:23 -0700 | [diff] [blame] | 213 | void RequestWriteCharacteristicCallback( |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 214 | hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id, |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 215 | const RawAddress& bda, int attr_handle, int offset, bool need_rsp, |
Pavlin Radoslavov | b324a8d | 2016-12-09 17:50:59 -0800 | [diff] [blame] | 216 | bool is_prep, std::vector<uint8_t> value) override; |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 217 | void RequestWriteDescriptorCallback(hal::BluetoothGattInterface* gatt_iface, |
| 218 | int conn_id, int trans_id, |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 219 | const RawAddress& bda, int attr_handle, |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 220 | int offset, bool need_rsp, bool is_prep, |
Pavlin Radoslavov | b324a8d | 2016-12-09 17:50:59 -0800 | [diff] [blame] | 221 | std::vector<uint8_t> value) override; |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 222 | void RequestExecWriteCallback(hal::BluetoothGattInterface* gatt_iface, |
| 223 | int conn_id, int trans_id, |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 224 | const RawAddress& bda, int exec_write) override; |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 225 | void IndicationSentCallback(hal::BluetoothGattInterface* gatt_iface, |
| 226 | int conn_id, int status) override; |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 227 | |
| 228 | // Helper function that notifies and clears the pending callback. |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 229 | void CleanUpPendingData(); |
| 230 | |
Arman Uguray | 9161374 | 2015-09-24 22:45:16 -0700 | [diff] [blame] | 231 | // Handles the next attribute entry in the pending service declaration. |
| 232 | void HandleNextEntry(hal::BluetoothGattInterface* gatt_iface); |
| 233 | |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 234 | // Helper method that returns a pointer to an internal Connection instance |
| 235 | // that matches the given parameters. |
Jakub Pawlowski | a484a88 | 2017-06-24 17:30:18 -0700 | [diff] [blame] | 236 | std::shared_ptr<Connection> GetConnection(int conn_id, const RawAddress& bda, |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 237 | int request_id); |
| 238 | |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 239 | // See getters for documentation. |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 240 | Uuid app_identifier_; |
Arman Uguray | bb18c41 | 2015-11-12 13:44:31 -0800 | [diff] [blame] | 241 | int server_id_; |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 242 | |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 243 | // Mutex that synchronizes access to the entries below. |
| 244 | std::mutex mutex_; |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 245 | ResultCallback pending_end_decl_cb_; |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 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 | |
Arman Uguray | cd644e3 | 2015-10-01 16:36:38 -0700 | [diff] [blame] | 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 | |
Arman Uguray | 514bf60 | 2015-09-29 19:38:03 -0700 | [diff] [blame] | 262 | // Raw handle to the Delegate, which must outlive this GattServer instance. |
| 263 | Delegate* delegate_; |
Arman Uguray | df0b271 | 2015-09-23 17:25:54 -0700 | [diff] [blame] | 264 | |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 265 | DISALLOW_COPY_AND_ASSIGN(GattServer); |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 266 | }; |
| 267 | |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 268 | // GattServerFactory is used to register and obtain a per-application GattServer |
Arman Uguray | 50a3154 | 2015-11-10 18:03:36 -0800 | [diff] [blame] | 269 | // instance. Users should call RegisterClient to obtain their own unique |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 270 | // GattServer instance that has been registered with the Bluetooth stack. |
Arman Uguray | bb18c41 | 2015-11-12 13:44:31 -0800 | [diff] [blame] | 271 | class GattServerFactory : public BluetoothInstanceFactory, |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 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 | |
Arman Uguray | bb18c41 | 2015-11-12 13:44:31 -0800 | [diff] [blame] | 279 | // BluetoothInstanceFactory override: |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 280 | bool RegisterInstance(const Uuid& uuid, |
Arman Uguray | bb18c41 | 2015-11-12 13:44:31 -0800 | [diff] [blame] | 281 | const RegisterCallback& callback) override; |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 282 | |
| 283 | private: |
| 284 | // hal::BluetoothGattInterface::ServerObserver override: |
Myles Watson | 911d1ae | 2016-11-28 16:44:40 -0800 | [diff] [blame] | 285 | void RegisterServerCallback(hal::BluetoothGattInterface* gatt_iface, |
| 286 | int status, int server_id, |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 287 | const Uuid& app_uuid) override; |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 288 | |
| 289 | // Map of pending calls to register. |
| 290 | std::mutex pending_calls_lock_; |
Jakub Pawlowski | 819e2ec | 2017-07-10 09:56:09 -0700 | [diff] [blame] | 291 | std::unordered_map<Uuid, RegisterCallback> pending_calls_; |
Arman Uguray | 0f2d489 | 2015-09-22 14:20:42 -0700 | [diff] [blame] | 292 | |
| 293 | DISALLOW_COPY_AND_ASSIGN(GattServerFactory); |
| 294 | }; |
| 295 | |
Ian Coolidge | 611fcf9 | 2015-06-03 17:20:30 -0700 | [diff] [blame] | 296 | } // namespace bluetooth |