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 <bluetooth/uuid.h> 20 21 #include <atomic> 22 #include <functional> 23 #include <map> 24 #include <mutex> 25 26 #include "service/bluetooth_instance.h" 27 #include "service/common/bluetooth/low_energy_constants.h" 28 #include "service/common/bluetooth/scan_filter.h" 29 #include "service/common/bluetooth/scan_result.h" 30 #include "service/common/bluetooth/scan_settings.h" 31 #include "service/hal/bluetooth_gatt_interface.h" 32 #include "types/raw_address.h" 33 34 namespace bluetooth { 35 36 struct ConnComparator { operatorConnComparator37 bool operator()(const RawAddress& a, const RawAddress& b) const { 38 return memcmp(a.address, b.address, RawAddress::kLength) < 0; 39 } 40 }; 41 42 class Adapter; 43 44 // A LowEnergyClient represents an application's handle to perform various 45 // Bluetooth Low Energy GAP operations. Instances cannot be created directly and 46 // should be obtained through the factory. 47 class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver, 48 public BluetoothInstance { 49 public: 50 // The Delegate interface is used to notify asynchronous events related to BLE 51 // GAP operations. 52 class Delegate { 53 public: 54 Delegate() = default; 55 Delegate(const Delegate&) = delete; 56 Delegate& operator=(const Delegate&) = delete; 57 58 virtual ~Delegate() = default; 59 60 // Called asynchronously to notify the delegate of connection state change 61 virtual void OnConnectionState(LowEnergyClient* client, int status, 62 const char* address, bool connected) = 0; 63 64 // Called asynchronously to notify the delegate of mtu change 65 virtual void OnMtuChanged(LowEnergyClient* client, int status, 66 const char* address, int mtu) = 0; 67 }; 68 69 LowEnergyClient(const LowEnergyClient&) = delete; 70 LowEnergyClient& operator=(const LowEnergyClient&) = delete; 71 72 // The destructor automatically unregisters this client instance from the 73 // stack. 74 ~LowEnergyClient() override; 75 76 // Assigns a delegate to this instance. |delegate| must out-live this 77 // LowEnergyClient instance. 78 void SetDelegate(Delegate* delegate); 79 80 // Callback type used to return the result of asynchronous operations below. 81 using StatusCallback = std::function<void(BLEStatus)>; 82 83 // Initiates a BLE connection do device with address |address|. If 84 // |is_direct| is set, use direct connect procedure. Return true on success 85 //, false otherwise. 86 bool Connect(const std::string& address, bool is_direct); 87 88 // Disconnect from previously connected BLE device with address |address|. 89 // Return true on success, false otherwise. 90 bool Disconnect(const std::string& address); 91 92 // Sends request to set MTU to |mtu| for device with address |address|. 93 // Return true on success, false otherwise. 94 bool SetMtu(const std::string& address, int mtu); 95 96 // BluetoothClientInstace overrides: 97 const Uuid& GetAppIdentifier() const override; 98 int GetInstanceId() const override; 99 100 private: 101 friend class LowEnergyClientFactory; 102 103 // Constructor shouldn't be called directly as instances are meant to be 104 // obtained from the factory. 105 LowEnergyClient(Adapter& adapter, const Uuid& uuid, int client_id); 106 107 // BluetoothGattInterface::ClientObserver overrides: 108 void ConnectCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id, 109 int status, int client_id, 110 const RawAddress& bda) override; 111 void DisconnectCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id, 112 int status, int client_id, 113 const RawAddress& bda) override; 114 void MtuChangedCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id, 115 int status, int mtu) override; 116 117 // Calls and clears the pending callbacks. 118 void InvokeAndClearStartCallback(BLEStatus status); 119 void InvokeAndClearStopCallback(BLEStatus status); 120 121 // Raw pointer to the Bluetooth Adapter. 122 Adapter& adapter_; 123 124 // See getters above for documentation. 125 Uuid app_identifier_; 126 int client_id_; 127 128 // Raw handle to the Delegate, which must outlive this LowEnergyClient 129 // instance. 130 std::mutex delegate_mutex_; 131 Delegate* delegate_; 132 133 // Protects device connection related members below. 134 std::mutex connection_fields_lock_; 135 136 // Maps bluetooth address to connection id 137 // TODO(jpawlowski): change type to bimap 138 std::map<const RawAddress, int, ConnComparator> connection_ids_; 139 }; 140 141 // LowEnergyClientFactory is used to register and obtain a per-application 142 // LowEnergyClient instance. Users should call RegisterInstance to obtain their 143 // own unique LowEnergyClient instance that has been registered with the 144 // Bluetooth stack. 145 class LowEnergyClientFactory 146 : private hal::BluetoothGattInterface::ClientObserver, 147 public BluetoothInstanceFactory { 148 public: 149 // Don't construct/destruct directly except in tests. Instead, obtain a handle 150 // from an Adapter instance. 151 explicit LowEnergyClientFactory(Adapter& adapter); 152 LowEnergyClientFactory(const LowEnergyClientFactory&) = delete; 153 LowEnergyClientFactory& operator=(const LowEnergyClientFactory&) = delete; 154 155 ~LowEnergyClientFactory() override; 156 157 // BluetoothInstanceFactory override: 158 bool RegisterInstance(const Uuid& uuid, 159 const RegisterCallback& callback) override; 160 161 private: 162 friend class LowEnergyClient; 163 164 // BluetoothGattInterface::ClientObserver overrides: 165 void RegisterClientCallback(hal::BluetoothGattInterface* gatt_iface, 166 int status, int client_id, 167 const bluetooth::Uuid& app_uuid) override; 168 169 // Map of pending calls to register. 170 std::mutex pending_calls_lock_; 171 std::map<Uuid, RegisterCallback> pending_calls_; 172 173 // Raw pointer to the Adapter that owns this factory. 174 Adapter& adapter_; 175 }; 176 177 } // namespace bluetooth 178