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