adapter.cpp revision 6791e9ab3892cbe61cf088eb1ebd7c4bfb2e603e
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 194fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include <base/logging.h> 204fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 214fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include "service/logging_helpers.h" 224fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 236791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayusing std::lock_guard; 246791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayusing std::mutex; 256791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 264fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraynamespace bluetooth { 274fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static 2903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultAddress[] = "00:00:00:00:00:00"; 3003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static 3103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultName[] = "not-initialized"; 3203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 336791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// TODO(armansito): The following constants come straight from 346791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be 356791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// nice to know if there were a way to obtain these values from the stack 366791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// instead of hardcoding them here. 376791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 3810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// The minimum number of advertising instances required for multi-advertisement 3910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// support. 406791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinAdvInstancesForMultiAdv = 5; 416791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 426791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// Used when determining if offloaded scan filtering is supported. 436791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinOffloadedFilters = 10; 446791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 456791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// Used when determining if offloaded scan batching is supported. 466791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinOffloadedScanStorageBytes = 1024; 4710b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray 484cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::Observer::OnAdapterStateChanged(Adapter* adapter, 494cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray AdapterState prev_state, 504cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray AdapterState new_state) { 514cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray // Default implementation does nothing 524cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray} 534cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 540f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Ugurayvoid Adapter::Observer::OnDeviceConnectionStateChanged( 550f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray Adapter* adapter, const std::string& device_address, bool connected) { 560f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray // Default implementation does nothing 570f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray} 580f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 5903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman UgurayAdapter::Adapter() 6003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray : state_(ADAPTER_STATE_OFF), 6103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray address_(kDefaultAddress), 6203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray name_(kDefaultName) { 6310b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray memset(&local_le_features_, 0, sizeof(local_le_features_)); 644fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray hal::BluetoothInterface::Get()->AddObserver(this); 65c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray ble_client_factory_.reset(new LowEnergyClientFactory()); 6650a31545d2d20d92d161c51195b653eafd164025Arman Uguray gatt_client_factory_.reset(new GattClientFactory()); 670f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray gatt_server_factory_.reset(new GattServerFactory()); 682117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties(); 694fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 704fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 714fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman UgurayAdapter::~Adapter() { 724fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray hal::BluetoothInterface::Get()->RemoveObserver(this); 734fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 744fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 754cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::AddObserver(Observer* observer) { 766791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(observers_lock_); 774cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray observers_.AddObserver(observer); 784cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray} 794cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 804cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::RemoveObserver(Observer* observer) { 816791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(observers_lock_); 824cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray observers_.RemoveObserver(observer); 834cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray} 844cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 852117e520c9f5b105ade7e92c4ab4928ea905f176Arman UgurayAdapterState Adapter::GetState() const { 862117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray return state_.load(); 872117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray} 882117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 892117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguraybool Adapter::IsEnabled() const { 902117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray return state_.load() == ADAPTER_STATE_ON; 914fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 924fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 934fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::Enable() { 942117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray AdapterState current_state = GetState(); 952117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray if (current_state != ADAPTER_STATE_OFF) { 962117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray LOG(INFO) << "Adapter not disabled - state: " 972117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray << AdapterStateToString(current_state); 984fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return false; 994fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1004fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1012117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray // Set the state before calling enable() as there might be a race between here 1022117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray // and the AdapterStateChangedCallback. 1032117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray state_ = ADAPTER_STATE_TURNING_ON; 1044cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray NotifyAdapterStateChanged(current_state, state_); 1052117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 1064fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable(); 1074fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray if (status != BT_STATUS_SUCCESS) { 1084fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray LOG(ERROR) << "Failed to enable Bluetooth - status: " 1094fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray << BtStatusText((const bt_status_t)status); 1102117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray state_ = ADAPTER_STATE_OFF; 1114cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_); 1124fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return false; 1134fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1144fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1154fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return true; 1164fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 1174fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1184fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::Disable() { 1192117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray if (!IsEnabled()) { 1202117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray LOG(INFO) << "Adapter is not enabled"; 1214fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return false; 1224fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1234fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1242117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray AdapterState current_state = GetState(); 1252117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 1262117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray // Set the state before calling enable() as there might be a race between here 1272117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray // and the AdapterStateChangedCallback. 1282117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray state_ = ADAPTER_STATE_TURNING_OFF; 1294cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray NotifyAdapterStateChanged(current_state, state_); 1302117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 1314fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable(); 1324fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray if (status != BT_STATUS_SUCCESS) { 1334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray LOG(ERROR) << "Failed to disable Bluetooth - status: " 1344fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray << BtStatusText((const bt_status_t)status); 1352117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray state_ = current_state; 1364cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_); 1374fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return false; 1384fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1394fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1404fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return true; 1414fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 1424fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 14303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguraystd::string Adapter::GetName() const { 14403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray return name_.Get(); 14503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray} 14603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 1474fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::SetName(const std::string& name) { 1484fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray bt_bdname_t hal_name; 1494fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray size_t max_name_len = sizeof(hal_name.name); 1504fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1514fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray // Include the \0 byte in size measurement. 1524fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray if (name.length() >= max_name_len) { 1534fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum allowed" 1544fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray << " size: " << max_name_len; 1554fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return false; 1564fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1574fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1584fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(), 1594fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray name.length() + 1); 1604fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1614fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray VLOG(1) << "Setting adapter name: " << name; 1624fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1634fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) { 1644fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray LOG(ERROR) << "Failed to set adapter name: " << name; 1654fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return false; 1664fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 1674fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 1684fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return true; 1694fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 1704fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 17103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguraystd::string Adapter::GetAddress() const { 17203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray return address_.Get(); 17303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray} 17403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 1756791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguraybool Adapter::IsMultiAdvertisementSupported() { 1766791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 17710b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv; 17810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray} 17910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray 1800f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguraybool Adapter::IsDeviceConnected(const std::string& device_address) { 1816791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(connected_devices_lock_); 1820f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray return connected_devices_.find(device_address) != connected_devices_.end(); 1830f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray} 1840f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 1856791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayint Adapter::GetTotalNumberOfTrackableAdvertisements() { 1866791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 1876791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray return local_le_features_.total_trackable_advertisers; 1886791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray} 1896791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 1906791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguraybool Adapter::IsOffloadedFilteringSupported() { 1916791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 1926791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray return local_le_features_.max_adv_filter_supported >= kMinOffloadedFilters; 1936791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray} 1946791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 1956791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguraybool Adapter::IsOffloadedScanBatchingSupported() { 1966791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 1976791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray return local_le_features_.scan_result_storage_size >= 1986791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray kMinOffloadedScanStorageBytes; 1996791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray} 2006791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray 201c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman UgurayLowEnergyClientFactory* Adapter::GetLowEnergyClientFactory() const { 202c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray return ble_client_factory_.get(); 203c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray} 204c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 20550a31545d2d20d92d161c51195b653eafd164025Arman UgurayGattClientFactory* Adapter::GetGattClientFactory() const { 20650a31545d2d20d92d161c51195b653eafd164025Arman Uguray return gatt_client_factory_.get(); 20750a31545d2d20d92d161c51195b653eafd164025Arman Uguray} 20850a31545d2d20d92d161c51195b653eafd164025Arman Uguray 2090f2d4897046f037a9f181f47f3d349a9dd646478Arman UgurayGattServerFactory* Adapter::GetGattServerFactory() const { 2100f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray return gatt_server_factory_.get(); 2110f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray} 2120f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 2134fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Ugurayvoid Adapter::AdapterStateChangedCallback(bt_state_t state) { 2144fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray LOG(INFO) << "Adapter state changed: " << BtStateText(state); 2154fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2164cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray AdapterState prev_state = GetState(); 2174cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 2184fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray switch (state) { 2194fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray case BT_STATE_OFF: 2202117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray state_ = ADAPTER_STATE_OFF; 2214fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray break; 2224fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2234fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray case BT_STATE_ON: 2242117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray state_ = ADAPTER_STATE_ON; 2254fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray break; 2264fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2274fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray default: 2284fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray NOTREACHED(); 2294fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 2302117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray 2314cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray NotifyAdapterStateChanged(prev_state, GetState()); 2324fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 2334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 23403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayvoid Adapter::AdapterPropertiesCallback(bt_status_t status, 23503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray int num_properties, 23603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray bt_property_t* properties) { 23703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray LOG(INFO) << "Adapter properties changed"; 23803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 23903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray if (status != BT_STATUS_SUCCESS) { 24003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray LOG(ERROR) << "status: " << BtStatusText(status); 24103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray return; 24203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray } 24303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 24403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray for (int i = 0; i < num_properties; i++) { 24503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray bt_property_t* property = properties + i; 24603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray switch (property->type) { 24703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray case BT_PROPERTY_BDADDR: { 24803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>( 24903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray property->val)); 25003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray LOG(INFO) << "Adapter address changed: " << address; 25103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray address_.Set(address); 25203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray break; 25303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray } 25403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray case BT_PROPERTY_BDNAME: { 25503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val); 25603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray std::string name = reinterpret_cast<char*>(hal_name->name); 25703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray LOG(INFO) << "Adapter name changed: " << name; 25803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray name_.Set(name); 25903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray break; 26003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray } 26110b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray case BT_PROPERTY_LOCAL_LE_FEATURES: { 2626791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(local_le_features_lock_); 26310b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray if (property->len != sizeof(bt_local_le_features_t)) { 26410b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray LOG(WARNING) << "Malformed value received for property: " 26510b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray << "BT_PROPERTY_LOCAL_LE_FEATURES"; 26610b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray break; 26710b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray } 26810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray bt_local_le_features_t* features = 26910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray reinterpret_cast<bt_local_le_features_t*>(property->val); 27010b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray memcpy(&local_le_features_, features, sizeof(*features)); 27110b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray LOG(INFO) << "Supported LE features updated"; 27210b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray break; 27310b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray } 27403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray default: 27503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray VLOG(1) << "Unhandled adapter property: " 27603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray << BtPropertyText(property->type); 27703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray break; 27803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray } 27903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray 28003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray // TODO(armansito): notify others of the updated properties 28103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray } 2824fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 2834fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 2840f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Ugurayvoid Adapter::AclStateChangedCallback(bt_status_t status, 2850f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray const bt_bdaddr_t& remote_bdaddr, 2860f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray bt_acl_state_t state) { 2870f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray std::string device_address = BtAddrString(&remote_bdaddr); 2880f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray bool connected = (state == BT_ACL_STATE_CONNECTED); 2890f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray LOG(INFO) << "ACL state changed: " << device_address << " - connected: " 2900f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray << (connected ? "true" : "false"); 2910f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 2920f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray // If this is reported with an error status, I suppose the best thing we can 2930f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray // do is to log it and ignore the event. 2940f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray if (status != BT_STATUS_SUCCESS) { 2950f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray LOG(ERROR) << "AclStateChangedCallback called with status: " 2960f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray << BtStatusText(status); 2970f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray return; 2980f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray } 2990f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 3000f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray // Introduce a scope to manage |connected_devices_lock_| with RAII. 3010f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray { 3026791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(connected_devices_lock_); 3030f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray if (connected) 3040f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray connected_devices_.insert(device_address); 3050f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray else 3060f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray connected_devices_.erase(device_address); 3070f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray } 3080f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 3096791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(observers_lock_); 3100f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray FOR_EACH_OBSERVER( 3110f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray Observer, observers_, 3120f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray OnDeviceConnectionStateChanged(this, device_address, connected)); 3130f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray} 3140f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 3154fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::SetAdapterProperty(bt_property_type_t type, 3164fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray void* value, int length) { 3174fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray CHECK(length > 0); 3184fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray CHECK(value); 3194fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3204fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray bt_property_t property; 3214fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray property.len = length; 3224fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray property.val = value; 3234fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray property.type = type; 3244fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3254fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray int status = hal::BluetoothInterface::Get()->GetHALInterface()-> 3264fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray set_adapter_property(&property); 3274fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray if (status != BT_STATUS_SUCCESS) { 3284fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray VLOG(1) << "Failed to set property"; 3294fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return false; 3304fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray } 3314fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3324fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray return true; 3334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} 3344fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray 3354cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::NotifyAdapterStateChanged(AdapterState prev_state, 3364cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray AdapterState new_state) { 3374cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray if (prev_state == new_state) 3384cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray return; 3394cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 3406791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray lock_guard<mutex> lock(observers_lock_); 3414cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray FOR_EACH_OBSERVER(Observer, observers_, 3424cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray OnAdapterStateChanged(this, prev_state, new_state)); 3434cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray} 3444cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray 3454fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray} // namespace bluetooth 346