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