low_energy_client.h revision 2fea18e501ab98df3254a08fca981513bf098274
1// 2// Copyright (C) 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 <atomic> 20#include <functional> 21#include <map> 22#include <mutex> 23 24#include <base/macros.h> 25 26#include "hal/bluetooth_gatt_interface.h" 27#include "service/advertise_data.h" 28#include "service/advertise_settings.h" 29#include "service/low_energy_constants.h" 30#include "service/uuid.h" 31 32namespace bluetooth { 33 34// A LowEnergyClient represents an application's handle to perform various 35// Bluetooth Low Energy GAP operations. Instances cannot be created directly and 36// should be obtained through the factory. 37class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver { 38 public: 39 // The destructor automatically unregisters this client instance from the 40 // stack. 41 ~LowEnergyClient(); 42 43 // The app-specific unique ID used while registering this client. 44 const UUID& app_identifier() const { return app_identifier_; } 45 46 // The HAL bt_gatt_client "interface ID" assigned to us by the stack. This is 47 // what is used internally for BLE transactions. 48 int client_if() const { return client_if_; } 49 50 // Callback type used to return the result of asynchronous operations below. 51 using StatusCallback = std::function<void(BLEStatus)>; 52 53 // Starts advertising based on the given advertising and scan response 54 // data and the provided |settings|. Reports the result of the operation in 55 // |callback|. 56 bool StartAdvertising(const AdvertiseSettings& settings, 57 const AdvertiseData& advertise_data, 58 const AdvertiseData& scan_response, 59 const StatusCallback& callback); 60 61 // Stops advertising if it was already started. Reports the result of the 62 // operation in |callback|. 63 bool StopAdvertising(const StatusCallback& callback); 64 65 // Returns true if advertising has been started. 66 bool IsAdvertisingStarted() const; 67 68 // Returns the state of pending advertising operations. 69 bool IsStartingAdvertising() const; 70 bool IsStoppingAdvertising() const; 71 72 // Returns the current advertising settings. 73 const AdvertiseSettings& settings() const { return settings_; } 74 75 private: 76 friend class LowEnergyClientFactory; 77 78 // Constructor/destructor shouldn't be called directly as instances are meant 79 // to be obtained from the factory. 80 LowEnergyClient(const UUID& uuid, int client_if); 81 82 // BluetoothGattInterface::ClientObserver overrides: 83 void MultiAdvEnableCallback( 84 hal::BluetoothGattInterface* gatt_iface, 85 int client_if, int status) override; 86 void MultiAdvDataCallback( 87 hal::BluetoothGattInterface* gatt_iface, 88 int client_if, int status) override; 89 void MultiAdvDisableCallback( 90 hal::BluetoothGattInterface* gatt_iface, 91 int client_if, int status) override; 92 93 // Helper method called from SetAdvertiseData/SetScanResponse. 94 bt_status_t SetAdvertiseData( 95 hal::BluetoothGattInterface* gatt_iface, 96 const AdvertiseData& data, 97 bool set_scan_rsp); 98 99 // Handles deferred advertise/scan-response data updates. We set the data if 100 // there's data to be set, otherwise we either defer it if advertisements 101 // aren't enabled or do nothing. 102 void HandleDeferredAdvertiseData(hal::BluetoothGattInterface* gatt_iface); 103 104 // Calls and clears the pending callbacks. 105 void InvokeAndClearStartCallback(BLEStatus status); 106 void InvokeAndClearStopCallback(BLEStatus status); 107 108 // See getters above for documentation. 109 UUID app_identifier_; 110 int client_if_; 111 112 // Protects advertising-related members below. 113 std::mutex adv_fields_lock_; 114 115 // The advertising and scan response data fields that will be sent to the 116 // controller. 117 AdvertiseData adv_data_; 118 AdvertiseData scan_response_; 119 std::atomic_bool adv_data_needs_update_; 120 std::atomic_bool scan_rsp_needs_update_; 121 122 // Latest advertising settings. 123 AdvertiseSettings settings_; 124 125 // Whether or not there is a pending call to update advertising or scan 126 // response data. 127 std::atomic_bool is_setting_adv_data_; 128 129 std::atomic_bool adv_started_; 130 std::unique_ptr<StatusCallback> adv_start_callback_; 131 std::unique_ptr<StatusCallback> adv_stop_callback_; 132 133 DISALLOW_COPY_AND_ASSIGN(LowEnergyClient); 134}; 135 136// LowEnergyClientFactory is used to register and obtain a per-application 137// LowEnergyClient instance. Users should call RegisterClient to obtain their 138// own unique LowEnergyClient instance that has been registered with the 139// Bluetooth stack. 140class LowEnergyClientFactory 141 : private hal::BluetoothGattInterface::ClientObserver { 142 public: 143 // Don't construct/destruct directly except in tests. Instead, obtain a handle 144 // from an Adapter instance.. 145 LowEnergyClientFactory(); 146 ~LowEnergyClientFactory(); 147 148 // Registers a LowEnergyClient for the given unique identifier |uuid|. On 149 // success, this asynchronously invokes |callback| with a unique pointer to a 150 // LowEnergyClient instance whose ownership can be taken by the caller. In the 151 // case of an error, the pointer will contain a nullptr. 152 using ClientCallback = 153 std::function< 154 void(BLEStatus, const UUID&, std::unique_ptr<LowEnergyClient>)>; 155 bool RegisterClient(const UUID& uuid, const ClientCallback& callback); 156 157 private: 158 // BluetoothGattInterface::ClientObserver overrides: 159 void RegisterClientCallback( 160 hal::BluetoothGattInterface* gatt_iface, 161 int status, int client_if, 162 const bt_uuid_t& app_uuid) override; 163 164 // Map of pending calls to register. 165 std::mutex pending_calls_lock_; 166 std::map<UUID, ClientCallback> pending_calls_; 167 168 DISALLOW_COPY_AND_ASSIGN(LowEnergyClientFactory); 169}; 170 171} // namespace bluetooth 172