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#include "service/adapter.h" 18 19#include <atomic> 20#include <mutex> 21#include <string> 22#include <unordered_set> 23 24#include <base/logging.h> 25#include <base/observer_list.h> 26 27#include "service/common/bluetooth/util/atomic_string.h" 28#include "service/gatt_client.h" 29#include "service/gatt_server.h" 30#include "service/hal/bluetooth_interface.h" 31#include "service/logging_helpers.h" 32#include "service/low_energy_client.h" 33 34using std::lock_guard; 35using std::mutex; 36 37namespace bluetooth { 38 39// static 40const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00"; 41// static 42const char Adapter::kDefaultName[] = "not-initialized"; 43 44// TODO(armansito): The following constants come straight from 45// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be 46// nice to know if there were a way to obtain these values from the stack 47// instead of hardcoding them here. 48 49// The minimum number of advertising instances required for multi-advertisement 50// support. 51const int kMinAdvInstancesForMultiAdv = 5; 52 53// Used when determining if offloaded scan filtering is supported. 54const int kMinOffloadedFilters = 10; 55 56// Used when determining if offloaded scan batching is supported. 57const int kMinOffloadedScanStorageBytes = 1024; 58 59void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter, 60 AdapterState prev_state, 61 AdapterState new_state) { 62 // Default implementation does nothing 63} 64 65void Adapter::Observer::OnDeviceConnectionStateChanged( 66 Adapter* adapter, const std::string& device_address, bool connected) { 67 // Default implementation does nothing 68} 69 70// The real Adapter implementation used in production. 71class AdapterImpl : public Adapter, 72 public hal::BluetoothInterface::Observer { 73 public: 74 AdapterImpl() 75 : state_(ADAPTER_STATE_OFF), 76 address_(kDefaultAddress), 77 name_(kDefaultName) { 78 memset(&local_le_features_, 0, sizeof(local_le_features_)); 79 hal::BluetoothInterface::Get()->AddObserver(this); 80 ble_client_factory_.reset(new LowEnergyClientFactory(*this)); 81 gatt_client_factory_.reset(new GattClientFactory()); 82 gatt_server_factory_.reset(new GattServerFactory()); 83 hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties(); 84 } 85 86 ~AdapterImpl() override { 87 hal::BluetoothInterface::Get()->RemoveObserver(this); 88 } 89 90 void AddObserver(Adapter::Observer* observer) override { 91 lock_guard<mutex> lock(observers_lock_); 92 observers_.AddObserver(observer); 93 } 94 95 void RemoveObserver(Adapter::Observer* observer) override { 96 lock_guard<mutex> lock(observers_lock_); 97 observers_.RemoveObserver(observer); 98 } 99 100 AdapterState GetState() const override { 101 return state_.load(); 102 } 103 104 bool IsEnabled() const override { 105 return state_.load() == ADAPTER_STATE_ON; 106 } 107 108 bool Enable(bool start_restricted) override { 109 AdapterState current_state = GetState(); 110 if (current_state != ADAPTER_STATE_OFF) { 111 LOG(INFO) << "Adapter not disabled - state: " 112 << AdapterStateToString(current_state); 113 return false; 114 } 115 116 // Set the state before calling enable() as there might be a race between 117 // here and the AdapterStateChangedCallback. 118 state_ = ADAPTER_STATE_TURNING_ON; 119 NotifyAdapterStateChanged(current_state, state_); 120 121 int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable(start_restricted); 122 if (status != BT_STATUS_SUCCESS) { 123 LOG(ERROR) << "Failed to enable Bluetooth - status: " 124 << BtStatusText((const bt_status_t)status); 125 state_ = ADAPTER_STATE_OFF; 126 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_); 127 return false; 128 } 129 130 return true; 131 } 132 133 bool Disable() override { 134 if (!IsEnabled()) { 135 LOG(INFO) << "Adapter is not enabled"; 136 return false; 137 } 138 139 AdapterState current_state = GetState(); 140 141 // Set the state before calling enable() as there might be a race between 142 // here and the AdapterStateChangedCallback. 143 state_ = ADAPTER_STATE_TURNING_OFF; 144 NotifyAdapterStateChanged(current_state, state_); 145 146 int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable(); 147 if (status != BT_STATUS_SUCCESS) { 148 LOG(ERROR) << "Failed to disable Bluetooth - status: " 149 << BtStatusText((const bt_status_t)status); 150 state_ = current_state; 151 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_); 152 return false; 153 } 154 155 return true; 156 } 157 158 std::string GetName() const override { 159 return name_.Get(); 160 } 161 162 bool SetName(const std::string& name) override { 163 bt_bdname_t hal_name; 164 size_t max_name_len = sizeof(hal_name.name); 165 166 // Include the \0 byte in size measurement. 167 if (name.length() >= max_name_len) { 168 LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum" 169 << " allowed size: " << max_name_len; 170 return false; 171 } 172 173 strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(), 174 name.length() + 1); 175 176 VLOG(1) << "Setting adapter name: " << name; 177 178 if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) { 179 LOG(ERROR) << "Failed to set adapter name: " << name; 180 return false; 181 } 182 183 return true; 184 } 185 186 std::string GetAddress() const override { 187 return address_.Get(); 188 } 189 190 bool IsMultiAdvertisementSupported() override { 191 lock_guard<mutex> lock(local_le_features_lock_); 192 return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv; 193 } 194 195 bool IsDeviceConnected(const std::string& device_address) override { 196 lock_guard<mutex> lock(connected_devices_lock_); 197 return connected_devices_.find(device_address) != connected_devices_.end(); 198 } 199 200 int GetTotalNumberOfTrackableAdvertisements() override { 201 lock_guard<mutex> lock(local_le_features_lock_); 202 return local_le_features_.total_trackable_advertisers; 203 } 204 205 bool IsOffloadedFilteringSupported() override { 206 lock_guard<mutex> lock(local_le_features_lock_); 207 return local_le_features_.max_adv_filter_supported >= kMinOffloadedFilters; 208 } 209 210 bool IsOffloadedScanBatchingSupported() override { 211 lock_guard<mutex> lock(local_le_features_lock_); 212 return local_le_features_.scan_result_storage_size >= 213 kMinOffloadedScanStorageBytes; 214 } 215 216 LowEnergyClientFactory* GetLowEnergyClientFactory() const override { 217 return ble_client_factory_.get(); 218 } 219 220 GattClientFactory* GetGattClientFactory() const override { 221 return gatt_client_factory_.get(); 222 } 223 224 GattServerFactory* GetGattServerFactory() const override { 225 return gatt_server_factory_.get(); 226 } 227 228 // hal::BluetoothInterface::Observer overrides. 229 void AdapterStateChangedCallback(bt_state_t state) override { 230 LOG(INFO) << "Adapter state changed: " << BtStateText(state); 231 232 AdapterState prev_state = GetState(); 233 234 switch (state) { 235 case BT_STATE_OFF: 236 state_ = ADAPTER_STATE_OFF; 237 break; 238 239 case BT_STATE_ON: 240 state_ = ADAPTER_STATE_ON; 241 break; 242 243 default: 244 NOTREACHED(); 245 } 246 247 NotifyAdapterStateChanged(prev_state, GetState()); 248 } 249 250 void AdapterPropertiesCallback(bt_status_t status, 251 int num_properties, 252 bt_property_t* properties) override { 253 LOG(INFO) << "Adapter properties changed"; 254 255 if (status != BT_STATUS_SUCCESS) { 256 LOG(ERROR) << "status: " << BtStatusText(status); 257 return; 258 } 259 260 for (int i = 0; i < num_properties; i++) { 261 bt_property_t* property = properties + i; 262 switch (property->type) { 263 case BT_PROPERTY_BDADDR: { 264 std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>( 265 property->val)); 266 LOG(INFO) << "Adapter address changed: " << address; 267 address_.Set(address); 268 break; 269 } 270 case BT_PROPERTY_BDNAME: { 271 bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val); 272 std::string name = reinterpret_cast<char*>(hal_name->name); 273 LOG(INFO) << "Adapter name changed: " << name; 274 name_.Set(name); 275 break; 276 } 277 case BT_PROPERTY_LOCAL_LE_FEATURES: { 278 lock_guard<mutex> lock(local_le_features_lock_); 279 if (property->len != sizeof(bt_local_le_features_t)) { 280 LOG(WARNING) << "Malformed value received for property: " 281 << "BT_PROPERTY_LOCAL_LE_FEATURES"; 282 break; 283 } 284 bt_local_le_features_t* features = 285 reinterpret_cast<bt_local_le_features_t*>(property->val); 286 memcpy(&local_le_features_, features, sizeof(*features)); 287 LOG(INFO) << "Supported LE features updated"; 288 break; 289 } 290 default: 291 VLOG(1) << "Unhandled adapter property: " 292 << BtPropertyText(property->type); 293 break; 294 } 295 296 // TODO(armansito): notify others of the updated properties 297 } 298 } 299 300 void AclStateChangedCallback(bt_status_t status, 301 const bt_bdaddr_t& remote_bdaddr, 302 bt_acl_state_t state) override { 303 std::string device_address = BtAddrString(&remote_bdaddr); 304 bool connected = (state == BT_ACL_STATE_CONNECTED); 305 LOG(INFO) << "ACL state changed: " << device_address << " - connected: " 306 << (connected ? "true" : "false"); 307 308 // If this is reported with an error status, I suppose the best thing we can 309 // do is to log it and ignore the event. 310 if (status != BT_STATUS_SUCCESS) { 311 LOG(ERROR) << "status: " << BtStatusText(status); 312 return; 313 } 314 315 // Introduce a scope to manage |connected_devices_lock_| with RAII. 316 { 317 lock_guard<mutex> lock(connected_devices_lock_); 318 if (connected) 319 connected_devices_.insert(device_address); 320 else 321 connected_devices_.erase(device_address); 322 } 323 324 lock_guard<mutex> lock(observers_lock_); 325 FOR_EACH_OBSERVER( 326 Adapter::Observer, observers_, 327 OnDeviceConnectionStateChanged(this, device_address, connected)); 328 } 329 330 // Sends a request to set the given HAL adapter property type and value. 331 bool SetAdapterProperty(bt_property_type_t type, void* value, int length) { 332 CHECK(length > 0); 333 CHECK(value); 334 335 bt_property_t property; 336 property.len = length; 337 property.val = value; 338 property.type = type; 339 340 int status = hal::BluetoothInterface::Get()->GetHALInterface()-> 341 set_adapter_property(&property); 342 if (status != BT_STATUS_SUCCESS) { 343 VLOG(1) << "Failed to set property"; 344 return false; 345 } 346 347 return true; 348 } 349 350 // Helper for invoking the AdapterStateChanged observer method. 351 void NotifyAdapterStateChanged(AdapterState prev_state, 352 AdapterState new_state) { 353 if (prev_state == new_state) 354 return; 355 356 lock_guard<mutex> lock(observers_lock_); 357 FOR_EACH_OBSERVER(Adapter::Observer, observers_, 358 OnAdapterStateChanged(this, prev_state, new_state)); 359 } 360 361 private: 362 // The current adapter state. 363 std::atomic<AdapterState> state_; 364 365 // The Bluetooth device address of the local adapter in string from 366 // (i.e.. XX:XX:XX:XX:XX:XX) 367 util::AtomicString address_; 368 369 // The current local adapter name. 370 util::AtomicString name_; 371 372 // The current set of supported LE features as obtained from the stack. The 373 // values here are all initially set to 0 and updated when the corresponding 374 // adapter property has been received from the stack. 375 std::mutex local_le_features_lock_; 376 bt_local_le_features_t local_le_features_; 377 378 // List of observers that are interested in notifications from us. 379 std::mutex observers_lock_; 380 base::ObserverList<Adapter::Observer> observers_; 381 382 // List of devices addresses that are currently connected. 383 std::mutex connected_devices_lock_; 384 std::unordered_set<std::string> connected_devices_; 385 386 // Factory used to create per-app LowEnergyClient instances. 387 std::unique_ptr<LowEnergyClientFactory> ble_client_factory_; 388 389 // Factory used to create per-app GattClient instances. 390 std::unique_ptr<GattClientFactory> gatt_client_factory_; 391 392 // Factory used to create per-app GattServer instances. 393 std::unique_ptr<GattServerFactory> gatt_server_factory_; 394 395 DISALLOW_COPY_AND_ASSIGN(AdapterImpl); 396}; 397 398// static 399std::unique_ptr<Adapter> Adapter::Create() { 400 return std::unique_ptr<Adapter>(new AdapterImpl()); 401} 402 403} // namespace bluetooth 404