Home | History | Annotate | Download | only in service
      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 {
    172     Connection(int conn_id, const RawAddress& bdaddr)
    173         : conn_id(conn_id), bdaddr(bdaddr) {}
    174     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 {
    183     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