14fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// 24fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// Copyright (C) 2015 Google, Inc. 34fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// 44fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// Licensed under the Apache License, Version 2.0 (the "License"); 54fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// you may not use this file except in compliance with the License. 64fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// You may obtain a copy of the License at: 74fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// 84fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// http://www.apache.org/licenses/LICENSE-2.0 94fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// 104fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// Unless required by applicable law or agreed to in writing, software 114fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// distributed under the License is distributed on an "AS IS" BASIS, 124fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// See the License for the specific language governing permissions and 144fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// limitations under the License. 154fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray// 164fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 174fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include "service/adapter.h" 184fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 190a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <atomic> 200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <mutex> 210a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <string> 220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <unordered_set> 230a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 244fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include <base/logging.h> 250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <base/observer_list.h> 264fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 270a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/common/bluetooth/util/atomic_string.h" 280a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/gatt_client.h" 290a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/gatt_server.h" 300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/hal/bluetooth_interface.h" 314fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include "service/logging_helpers.h" 320a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/low_energy_client.h" 334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 346791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayusing std::lock_guard; 356791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayusing std::mutex; 366791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 374fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraynamespace bluetooth { 384fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static 4003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultAddress[] = "00:00:00:00:00:00"; 4103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static 4203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultName[] = "not-initialized"; 4303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 446791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// TODO(armansito): The following constants come straight from 456791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be 466791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// nice to know if there were a way to obtain these values from the stack 476791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// instead of hardcoding them here. 486791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 4910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// The minimum number of advertising instances required for multi-advertisement 5010b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// support. 516791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinAdvInstancesForMultiAdv = 5; 526791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 536791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// Used when determining if offloaded scan filtering is supported. 546791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinOffloadedFilters = 10; 556791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 566791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// Used when determining if offloaded scan batching is supported. 576791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinOffloadedScanStorageBytes = 1024; 5810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray 594cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::Observer::OnAdapterStateChanged(Adapter* adapter, 604cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray AdapterState prev_state, 614cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray AdapterState new_state) { 624cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray // Default implementation does nothing 634cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray} 644cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 650f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Ugurayvoid Adapter::Observer::OnDeviceConnectionStateChanged( 660f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray Adapter* adapter, const std::string& device_address, bool connected) { 670f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray // Default implementation does nothing 680f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray} 690f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray// The real Adapter implementation used in production. 710a0d3932136995a722cc125ef920679113d8ce0fArman Ugurayclass AdapterImpl : public Adapter, 720a0d3932136995a722cc125ef920679113d8ce0fArman Uguray public hal::BluetoothInterface::Observer { 730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray public: 740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray AdapterImpl() 7503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray : state_(ADAPTER_STATE_OFF), 7603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray address_(kDefaultAddress), 7703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray name_(kDefaultName) { 780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray memset(&local_le_features_, 0, sizeof(local_le_features_)); 790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray hal::BluetoothInterface::Get()->AddObserver(this); 8060b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski ble_client_factory_.reset(new LowEnergyClientFactory(*this)); 810a0d3932136995a722cc125ef920679113d8ce0fArman Uguray gatt_client_factory_.reset(new GattClientFactory()); 820a0d3932136995a722cc125ef920679113d8ce0fArman Uguray gatt_server_factory_.reset(new GattServerFactory()); 830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties(); 840a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 854cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray ~AdapterImpl() override { 870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray hal::BluetoothInterface::Get()->RemoveObserver(this); 880a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 894cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray void AddObserver(Adapter::Observer* observer) override { 910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(observers_lock_); 920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray observers_.AddObserver(observer); 930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 942117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 950a0d3932136995a722cc125ef920679113d8ce0fArman Uguray void RemoveObserver(Adapter::Observer* observer) override { 960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(observers_lock_); 970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray observers_.RemoveObserver(observer); 980a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 994fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray AdapterState GetState() const override { 1010a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return state_.load(); 1024fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1034fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1040a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool IsEnabled() const override { 1050a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return state_.load() == ADAPTER_STATE_ON; 1064fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1074fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 108c7087d2466a291185853a6b2a16f789233e3420fAjay Panicker bool Enable(bool start_restricted) override { 1090a0d3932136995a722cc125ef920679113d8ce0fArman Uguray AdapterState current_state = GetState(); 1100a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (current_state != ADAPTER_STATE_OFF) { 1110a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "Adapter not disabled - state: " 1120a0d3932136995a722cc125ef920679113d8ce0fArman Uguray << AdapterStateToString(current_state); 1130a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return false; 1140a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1154fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1160a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Set the state before calling enable() as there might be a race between 1170a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // here and the AdapterStateChangedCallback. 1180a0d3932136995a722cc125ef920679113d8ce0fArman Uguray state_ = ADAPTER_STATE_TURNING_ON; 1190a0d3932136995a722cc125ef920679113d8ce0fArman Uguray NotifyAdapterStateChanged(current_state, state_); 1200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 121c7087d2466a291185853a6b2a16f789233e3420fAjay Panicker int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable(start_restricted); 1220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (status != BT_STATUS_SUCCESS) { 1230a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(ERROR) << "Failed to enable Bluetooth - status: " 1240a0d3932136995a722cc125ef920679113d8ce0fArman Uguray << BtStatusText((const bt_status_t)status); 1250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray state_ = ADAPTER_STATE_OFF; 1260a0d3932136995a722cc125ef920679113d8ce0fArman Uguray NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_); 1270a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return false; 1280a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1290a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 1300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return true; 1314fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1324fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1330a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool Disable() override { 1340a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (!IsEnabled()) { 1350a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "Adapter is not enabled"; 1360a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return false; 1370a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1380a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 1390a0d3932136995a722cc125ef920679113d8ce0fArman Uguray AdapterState current_state = GetState(); 1400a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 1410a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Set the state before calling enable() as there might be a race between 1420a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // here and the AdapterStateChangedCallback. 1430a0d3932136995a722cc125ef920679113d8ce0fArman Uguray state_ = ADAPTER_STATE_TURNING_OFF; 1440a0d3932136995a722cc125ef920679113d8ce0fArman Uguray NotifyAdapterStateChanged(current_state, state_); 1452117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 1460a0d3932136995a722cc125ef920679113d8ce0fArman Uguray int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable(); 1470a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (status != BT_STATUS_SUCCESS) { 1480a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(ERROR) << "Failed to disable Bluetooth - status: " 1490a0d3932136995a722cc125ef920679113d8ce0fArman Uguray << BtStatusText((const bt_status_t)status); 1500a0d3932136995a722cc125ef920679113d8ce0fArman Uguray state_ = current_state; 1510a0d3932136995a722cc125ef920679113d8ce0fArman Uguray NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_); 1520a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return false; 1530a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1542117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 1550a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return true; 1564fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1574fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1580a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::string GetName() const override { 1590a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return name_.Get(); 1600a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1614fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1620a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool SetName(const std::string& name) override { 1630a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_bdname_t hal_name; 1640a0d3932136995a722cc125ef920679113d8ce0fArman Uguray size_t max_name_len = sizeof(hal_name.name); 16503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 1660a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Include the \0 byte in size measurement. 1670a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (name.length() >= max_name_len) { 1680a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum" 1690a0d3932136995a722cc125ef920679113d8ce0fArman Uguray << " allowed size: " << max_name_len; 1700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return false; 1710a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1724fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(), 1740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray name.length() + 1); 1754fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1760a0d3932136995a722cc125ef920679113d8ce0fArman Uguray VLOG(1) << "Setting adapter name: " << name; 1774fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) { 1790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(ERROR) << "Failed to set adapter name: " << name; 1800a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return false; 1810a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1824fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return true; 1844fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1854fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::string GetAddress() const override { 1870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return address_.Get(); 1880a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 1894fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool IsMultiAdvertisementSupported() override { 1910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 1920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv; 1930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 19403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 1950a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool IsDeviceConnected(const std::string& device_address) override { 1960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(connected_devices_lock_); 1970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return connected_devices_.find(device_address) != connected_devices_.end(); 1980a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 19910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray 2000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray int GetTotalNumberOfTrackableAdvertisements() override { 2010a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 2020a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return local_le_features_.total_trackable_advertisers; 2030a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2040f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 2050a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool IsOffloadedFilteringSupported() override { 2060a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 2070a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return local_le_features_.max_adv_filter_supported >= kMinOffloadedFilters; 2080a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2096791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 2100a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool IsOffloadedScanBatchingSupported() override { 2110a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 2120a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return local_le_features_.scan_result_storage_size >= 2130a0d3932136995a722cc125ef920679113d8ce0fArman Uguray kMinOffloadedScanStorageBytes; 2140a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2156791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 2160a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LowEnergyClientFactory* GetLowEnergyClientFactory() const override { 2170a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return ble_client_factory_.get(); 2180a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2196791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 2200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray GattClientFactory* GetGattClientFactory() const override { 2210a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return gatt_client_factory_.get(); 2220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 223c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 2240a0d3932136995a722cc125ef920679113d8ce0fArman Uguray GattServerFactory* GetGattServerFactory() const override { 2250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return gatt_server_factory_.get(); 2260a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 22750a31545d2d20d92d161c51195b653eafd164025Arman Uguray 2280a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // hal::BluetoothInterface::Observer overrides. 2290a0d3932136995a722cc125ef920679113d8ce0fArman Uguray void AdapterStateChangedCallback(bt_state_t state) override { 2300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "Adapter state changed: " << BtStateText(state); 2310f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 2320a0d3932136995a722cc125ef920679113d8ce0fArman Uguray AdapterState prev_state = GetState(); 2334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2340a0d3932136995a722cc125ef920679113d8ce0fArman Uguray switch (state) { 2350a0d3932136995a722cc125ef920679113d8ce0fArman Uguray case BT_STATE_OFF: 2360a0d3932136995a722cc125ef920679113d8ce0fArman Uguray state_ = ADAPTER_STATE_OFF; 2370a0d3932136995a722cc125ef920679113d8ce0fArman Uguray break; 2384cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 2390a0d3932136995a722cc125ef920679113d8ce0fArman Uguray case BT_STATE_ON: 2400a0d3932136995a722cc125ef920679113d8ce0fArman Uguray state_ = ADAPTER_STATE_ON; 2410a0d3932136995a722cc125ef920679113d8ce0fArman Uguray break; 2424fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2430a0d3932136995a722cc125ef920679113d8ce0fArman Uguray default: 2440a0d3932136995a722cc125ef920679113d8ce0fArman Uguray NOTREACHED(); 2450a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2464fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2470a0d3932136995a722cc125ef920679113d8ce0fArman Uguray NotifyAdapterStateChanged(prev_state, GetState()); 2484fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 2492117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 2500a0d3932136995a722cc125ef920679113d8ce0fArman Uguray void AdapterPropertiesCallback(bt_status_t status, 2510a0d3932136995a722cc125ef920679113d8ce0fArman Uguray int num_properties, 2520a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_property_t* properties) override { 2530a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "Adapter properties changed"; 25403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 2550a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (status != BT_STATUS_SUCCESS) { 2560a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(ERROR) << "status: " << BtStatusText(status); 2570a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return; 2580a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 25903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 2600a0d3932136995a722cc125ef920679113d8ce0fArman Uguray for (int i = 0; i < num_properties; i++) { 2610a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_property_t* property = properties + i; 2620a0d3932136995a722cc125ef920679113d8ce0fArman Uguray switch (property->type) { 2630a0d3932136995a722cc125ef920679113d8ce0fArman Uguray case BT_PROPERTY_BDADDR: { 2640a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>( 2650a0d3932136995a722cc125ef920679113d8ce0fArman Uguray property->val)); 2660a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "Adapter address changed: " << address; 2670a0d3932136995a722cc125ef920679113d8ce0fArman Uguray address_.Set(address); 2680a0d3932136995a722cc125ef920679113d8ce0fArman Uguray break; 2690a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray case BT_PROPERTY_BDNAME: { 2710a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val); 2720a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::string name = reinterpret_cast<char*>(hal_name->name); 2730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "Adapter name changed: " << name; 2740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray name_.Set(name); 2750a0d3932136995a722cc125ef920679113d8ce0fArman Uguray break; 2760a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2770a0d3932136995a722cc125ef920679113d8ce0fArman Uguray case BT_PROPERTY_LOCAL_LE_FEATURES: { 2780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 2790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (property->len != sizeof(bt_local_le_features_t)) { 2800a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(WARNING) << "Malformed value received for property: " 2810a0d3932136995a722cc125ef920679113d8ce0fArman Uguray << "BT_PROPERTY_LOCAL_LE_FEATURES"; 2820a0d3932136995a722cc125ef920679113d8ce0fArman Uguray break; 2830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 2840a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_local_le_features_t* features = 2850a0d3932136995a722cc125ef920679113d8ce0fArman Uguray reinterpret_cast<bt_local_le_features_t*>(property->val); 2860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray memcpy(&local_le_features_, features, sizeof(*features)); 2870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "Supported LE features updated"; 28810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray break; 28910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray } 2900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray default: 2910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray VLOG(1) << "Unhandled adapter property: " 2920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray << BtPropertyText(property->type); 2930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray break; 29410b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray } 29503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 2960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // TODO(armansito): notify others of the updated properties 2970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 29803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray } 2994fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray void AclStateChangedCallback(bt_status_t status, 3010a0d3932136995a722cc125ef920679113d8ce0fArman Uguray const bt_bdaddr_t& remote_bdaddr, 3020a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_acl_state_t state) override { 3030a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::string device_address = BtAddrString(&remote_bdaddr); 3040a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool connected = (state == BT_ACL_STATE_CONNECTED); 3050a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(INFO) << "ACL state changed: " << device_address << " - connected: " 3060a0d3932136995a722cc125ef920679113d8ce0fArman Uguray << (connected ? "true" : "false"); 3070a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3080a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // If this is reported with an error status, I suppose the best thing we can 3090a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // do is to log it and ignore the event. 3100a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (status != BT_STATUS_SUCCESS) { 3110a0d3932136995a722cc125ef920679113d8ce0fArman Uguray LOG(ERROR) << "status: " << BtStatusText(status); 3120a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return; 3130a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 3140a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3150a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Introduce a scope to manage |connected_devices_lock_| with RAII. 3160a0d3932136995a722cc125ef920679113d8ce0fArman Uguray { 3170a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(connected_devices_lock_); 3180a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (connected) 3190a0d3932136995a722cc125ef920679113d8ce0fArman Uguray connected_devices_.insert(device_address); 3200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray else 3210a0d3932136995a722cc125ef920679113d8ce0fArman Uguray connected_devices_.erase(device_address); 3220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 3230a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3240a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(observers_lock_); 3250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray FOR_EACH_OBSERVER( 3260a0d3932136995a722cc125ef920679113d8ce0fArman Uguray Adapter::Observer, observers_, 3270a0d3932136995a722cc125ef920679113d8ce0fArman Uguray OnDeviceConnectionStateChanged(this, device_address, connected)); 3280f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray } 3290f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 3300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Sends a request to set the given HAL adapter property type and value. 3310a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bool SetAdapterProperty(bt_property_type_t type, void* value, int length) { 3320a0d3932136995a722cc125ef920679113d8ce0fArman Uguray CHECK(length > 0); 3330a0d3932136995a722cc125ef920679113d8ce0fArman Uguray CHECK(value); 3340a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3350a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_property_t property; 3360a0d3932136995a722cc125ef920679113d8ce0fArman Uguray property.len = length; 3370a0d3932136995a722cc125ef920679113d8ce0fArman Uguray property.val = value; 3380a0d3932136995a722cc125ef920679113d8ce0fArman Uguray property.type = type; 3390a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3400a0d3932136995a722cc125ef920679113d8ce0fArman Uguray int status = hal::BluetoothInterface::Get()->GetHALInterface()-> 3410a0d3932136995a722cc125ef920679113d8ce0fArman Uguray set_adapter_property(&property); 3420a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (status != BT_STATUS_SUCCESS) { 3430a0d3932136995a722cc125ef920679113d8ce0fArman Uguray VLOG(1) << "Failed to set property"; 3440a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return false; 3450a0d3932136995a722cc125ef920679113d8ce0fArman Uguray } 3460a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3470a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return true; 3480f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray } 3490f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 3500a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Helper for invoking the AdapterStateChanged observer method. 3510a0d3932136995a722cc125ef920679113d8ce0fArman Uguray void NotifyAdapterStateChanged(AdapterState prev_state, 3520a0d3932136995a722cc125ef920679113d8ce0fArman Uguray AdapterState new_state) { 3530a0d3932136995a722cc125ef920679113d8ce0fArman Uguray if (prev_state == new_state) 3540a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return; 3550f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 3560a0d3932136995a722cc125ef920679113d8ce0fArman Uguray lock_guard<mutex> lock(observers_lock_); 3570a0d3932136995a722cc125ef920679113d8ce0fArman Uguray FOR_EACH_OBSERVER(Adapter::Observer, observers_, 3580a0d3932136995a722cc125ef920679113d8ce0fArman Uguray OnAdapterStateChanged(this, prev_state, new_state)); 3594fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 3604fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3610a0d3932136995a722cc125ef920679113d8ce0fArman Uguray private: 3620a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // The current adapter state. 3630a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::atomic<AdapterState> state_; 3640a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3650a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // The Bluetooth device address of the local adapter in string from 3660a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // (i.e.. XX:XX:XX:XX:XX:XX) 3670a0d3932136995a722cc125ef920679113d8ce0fArman Uguray util::AtomicString address_; 3680a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3690a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // The current local adapter name. 3700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray util::AtomicString name_; 3710a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3720a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // The current set of supported LE features as obtained from the stack. The 3730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // values here are all initially set to 0 and updated when the corresponding 3740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // adapter property has been received from the stack. 3750a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::mutex local_le_features_lock_; 3760a0d3932136995a722cc125ef920679113d8ce0fArman Uguray bt_local_le_features_t local_le_features_; 3770a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // List of observers that are interested in notifications from us. 3790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::mutex observers_lock_; 3800a0d3932136995a722cc125ef920679113d8ce0fArman Uguray base::ObserverList<Adapter::Observer> observers_; 3814fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3820a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // List of devices addresses that are currently connected. 3830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::mutex connected_devices_lock_; 3840a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::unordered_set<std::string> connected_devices_; 3854cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 3860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Factory used to create per-app LowEnergyClient instances. 3870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::unique_ptr<LowEnergyClientFactory> ble_client_factory_; 3880a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3890a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Factory used to create per-app GattClient instances. 3900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::unique_ptr<GattClientFactory> gatt_client_factory_; 3910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray // Factory used to create per-app GattServer instances. 3930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray std::unique_ptr<GattServerFactory> gatt_server_factory_; 3940a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3950a0d3932136995a722cc125ef920679113d8ce0fArman Uguray DISALLOW_COPY_AND_ASSIGN(AdapterImpl); 3960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray}; 3970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray 3980a0d3932136995a722cc125ef920679113d8ce0fArman Uguray// static 3990a0d3932136995a722cc125ef920679113d8ce0fArman Uguraystd::unique_ptr<Adapter> Adapter::Create() { 4000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray return std::unique_ptr<Adapter>(new AdapterImpl()); 4014cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray} 4024cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 4034fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} // namespace bluetooth 404