123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- //
- // Copyright 2015 Google, Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at:
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- #pragma once
- #include <deque>
- #include <functional>
- #include <mutex>
- #include <string>
- #include <unordered_map>
- #include <unordered_set>
- #include <vector>
- #include <base/macros.h>
- #include <bluetooth/uuid.h>
- #include "service/bluetooth_instance.h"
- #include "service/common/bluetooth/service.h"
- #include "service/hal/bluetooth_gatt_interface.h"
- namespace bluetooth {
- // A GattServer instance represents an application's handle to perform GATT
- // server-role operations. Instances cannot be created directly and should be
- // obtained through the factory.
- class GattServer : public BluetoothInstance,
- private hal::BluetoothGattInterface::ServerObserver {
- public:
- // Delegate interface is used to handle incoming requests and confirmations
- // for a GATT service.
- class Delegate {
- public:
- Delegate() = default;
- virtual ~Delegate() = default;
- // Called when there is an incoming read request for the characteristic with
- // ID |characteristic_id| from a remote device with address
- // |device_address|. |request_id| can be used to respond to this request by
- // calling SendResponse below.
- virtual void OnCharacteristicReadRequest(GattServer* gatt_server,
- const std::string& device_address,
- int request_id, int offset,
- bool is_long, uint16_t handle) = 0;
- // Called when there is an incoming read request for the descriptor with
- // ID |descriptor_id| from a remote device with address |device_address|.
- // |request_id| can be used to respond to this request by
- // calling SendResponse below.
- virtual void OnDescriptorReadRequest(GattServer* gatt_server,
- const std::string& device_address,
- int request_id, int offset,
- bool is_long, uint16_t handle) = 0;
- // Called when there is an incoming write request for the characteristic
- // with ID |characteristic_id| from a remote device with address
- // |device_address|. |request_id| can be used to respond to this request by
- // calling SendResponse, if the |need_response| parameter is true. Otherwise
- // this is a "Write Without Reponse" procedure and SendResponse will fail.
- // If |is_prepare_write| is true, then the write should not be committed
- // immediately as this is a "Prepared Write Request". Instead, the Delegate
- // should hold on to the value and either discard it or complete the write
- // when it receives the OnExecuteWriteRequest event.
- virtual void OnCharacteristicWriteRequest(
- GattServer* gatt_server, const std::string& device_address,
- int request_id, int offset, bool is_prepare_write, bool need_response,
- const std::vector<uint8_t>& value, uint16_t handle) = 0;
- // Called when there is an incoming write request for the descriptor
- // with ID |descriptor_id| from a remote device with address
- // |device_address|. |request_id| can be used to respond to this request by
- // calling SendResponse, if the |need_response| parameter is true. Otherwise
- // this is a "Write Without Response" procedure and SendResponse will fail.
- // If |is_prepare_write| is true, then the write should not be committed
- // immediately as this is a "Prepared Write Request". Instead, the Delegate
- // should hold on to the value and either discard it or complete the write
- // when it receives the OnExecuteWriteRequest event.
- virtual void OnDescriptorWriteRequest(
- GattServer* gatt_server, const std::string& device_address,
- int request_id, int offset, bool is_prepare_write, bool need_response,
- const std::vector<uint8_t>& value, uint16_t handle) = 0;
- // Called when there is an incoming "Execute Write Request". If |is_execute|
- // is true, then the Delegate should commit all previously prepared writes.
- // Otherwise, all prepared writes should be aborted. The Delegate should
- // call "SendResponse" to complete the procedure.
- virtual void OnExecuteWriteRequest(GattServer* gatt_server,
- const std::string& device_address,
- int request_id, bool is_execute) = 0;
- virtual void OnConnectionStateChanged(GattServer* gatt_server,
- const std::string& device_addres,
- bool connected) = 0;
- private:
- DISALLOW_COPY_AND_ASSIGN(Delegate);
- };
- // The desctructor automatically unregisters this instance from the stack.
- ~GattServer() override;
- // Assigns a delegate to this instance. |delegate| must out-live this
- // GattServer instance.
- void SetDelegate(Delegate* delegate);
- // BluetoothClientInstace overrides:
- const Uuid& GetAppIdentifier() const override;
- int GetInstanceId() const override;
- // Callback type used to report the status of an asynchronous GATT server
- // operation.
- using ResultCallback =
- std::function<void(BLEStatus status, const Service& id)>;
- using GattCallback = std::function<void(GATTError error)>;
- // Add service declaration. This method immediately
- // returns false if a service hasn't been started. Otherwise, |callback| will
- // be called asynchronously with the result of the operation.
- //
- // TODO(armansito): It is unclear to me what it means for this function to
- // fail. What is the state that we're in? Is the service declaration over so
- // we can add other services to this server instance? Do we need to clean up
- // all the entries or does the upper-layer need to remove the service? Or are
- // we in a stuck-state where the service declaration hasn't ended?
- bool AddService(const Service&, const ResultCallback& callback);
- // Sends a response for a pending notification. |request_id| and
- // |device_address| should match those that were received through one of the
- // Delegate callbacks. |value| and |offset| are used for read requests and
- // prepare write requests and should match the value of the attribute. Returns
- // false if the pending request could not be resolved using the given
- // parameters or if the call to the underlying stack fails.
- bool SendResponse(const std::string& device_address, int request_id,
- GATTError error, int offset,
- const std::vector<uint8_t>& value);
- // Sends an ATT Handle-Value Notification to the device with BD_ADDR
- // |device_address| for the characteristic with handle |handle| and
- // value |value|. If |confirm| is true, then an ATT Handle-Value Indication
- // will be sent instead, which requires the remote to confirm receipt. Returns
- // false if there was an immediate error in initiating the notification
- // procedure. Otherwise, returns true and reports the asynchronous result of
- // the operation in |callback|.
- //
- // If |confirm| is true, then |callback| will be run when the remote device
- // sends a ATT Handle-Value Confirmation packet. Otherwise, it will be run as
- // soon as the notification has been sent out.
- bool SendNotification(const std::string& device_address,
- const uint16_t handle, bool confirm,
- const std::vector<uint8_t>& value,
- const GattCallback& callback);
- private:
- friend class GattServerFactory;
- // Used for the internal remote connection tracking. Keeps track of the
- // request ID and the device address for the connection. If |request_id| is -1
- // then no ATT read/write request is currently pending.
- struct Connection {
- Connection(int conn_id, const RawAddress& bdaddr)
- : conn_id(conn_id), bdaddr(bdaddr) {}
- Connection() : conn_id(-1) { memset(&bdaddr, 0, sizeof(bdaddr)); }
- int conn_id;
- std::unordered_map<int, int> request_id_to_handle;
- RawAddress bdaddr;
- };
- // Used to keep track of a pending Handle-Value indication.
- struct PendingIndication {
- explicit PendingIndication(const GattCallback& callback)
- : has_success(false), callback(callback) {}
- bool has_success;
- GattCallback callback;
- };
- // Constructor shouldn't be called directly as instances are meant to be
- // obtained from the factory.
- GattServer(const Uuid& uuid, int server_id);
- // hal::BluetoothGattInterface::ServerObserver overrides:
- void ConnectionCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
- int server_id, int connected,
- const RawAddress& bda) override;
- void ServiceAddedCallback(hal::BluetoothGattInterface* gatt_iface, int status,
- int server_if,
- std::vector<btgatt_db_element_t>) override;
- void ServiceStoppedCallback(hal::BluetoothGattInterface* gatt_iface,
- int status, int server_id,
- int service_handle) override;
- void RequestReadCharacteristicCallback(
- hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
- const RawAddress& bda, int attribute_handle, int offset,
- bool is_long) override;
- void RequestReadDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
- int conn_id, int trans_id,
- const RawAddress& bda,
- int attribute_handle, int offset,
- bool is_long) override;
- void RequestWriteCharacteristicCallback(
- hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
- const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
- bool is_prep, std::vector<uint8_t> value) override;
- void RequestWriteDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
- int conn_id, int trans_id,
- const RawAddress& bda, int attr_handle,
- int offset, bool need_rsp, bool is_prep,
- std::vector<uint8_t> value) override;
- void RequestExecWriteCallback(hal::BluetoothGattInterface* gatt_iface,
- int conn_id, int trans_id,
- const RawAddress& bda, int exec_write) override;
- void IndicationSentCallback(hal::BluetoothGattInterface* gatt_iface,
- int conn_id, int status) override;
- // Helper function that notifies and clears the pending callback.
- void CleanUpPendingData();
- // Handles the next attribute entry in the pending service declaration.
- void HandleNextEntry(hal::BluetoothGattInterface* gatt_iface);
- // Helper method that returns a pointer to an internal Connection instance
- // that matches the given parameters.
- std::shared_ptr<Connection> GetConnection(int conn_id, const RawAddress& bda,
- int request_id);
- // See getters for documentation.
- Uuid app_identifier_;
- int server_id_;
- // Mutex that synchronizes access to the entries below.
- std::mutex mutex_;
- ResultCallback pending_end_decl_cb_;
- // GATT connection mappings from stack-provided "conn_id" IDs and remote
- // device addresses to Connection structures. The conn_id map is one-to-one
- // while the conn_addr map is one to many, as a remote device may support
- // multiple transports (BR/EDR & LE) and use the same device address for both.
- std::unordered_map<int, std::shared_ptr<Connection>> conn_id_map_;
- std::unordered_map<std::string, std::vector<std::shared_ptr<Connection>>>
- conn_addr_map_;
- // Connections for which a Handle-Value indication is pending. Since there can
- // be multiple indications to the same device (in the case of a dual-mode
- // device with simulatenous BR/EDR & LE GATT connections), we also keep track
- // of whether there has been at least one successful confirmation.
- std::unordered_map<int, std::shared_ptr<PendingIndication>>
- pending_indications_;
- // Raw handle to the Delegate, which must outlive this GattServer instance.
- Delegate* delegate_;
- DISALLOW_COPY_AND_ASSIGN(GattServer);
- };
- // GattServerFactory is used to register and obtain a per-application GattServer
- // instance. Users should call RegisterClient to obtain their own unique
- // GattServer instance that has been registered with the Bluetooth stack.
- class GattServerFactory : public BluetoothInstanceFactory,
- private hal::BluetoothGattInterface::ServerObserver {
- public:
- // Don't construct/destruct directly except in tests. Instead, obtain a handle
- // from an Adapter instance.
- GattServerFactory();
- ~GattServerFactory() override;
- // BluetoothInstanceFactory override:
- bool RegisterInstance(const Uuid& uuid,
- const RegisterCallback& callback) override;
- private:
- // hal::BluetoothGattInterface::ServerObserver override:
- void RegisterServerCallback(hal::BluetoothGattInterface* gatt_iface,
- int status, int server_id,
- const Uuid& app_uuid) override;
- // Map of pending calls to register.
- std::mutex pending_calls_lock_;
- std::unordered_map<Uuid, RegisterCallback> pending_calls_;
- DISALLOW_COPY_AND_ASSIGN(GattServerFactory);
- };
- } // namespace bluetooth
|