adapter.cpp revision 50a31545d2d20d92d161c51195b653eafd164025
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
234fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraynamespace bluetooth {
244fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static
2603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
2703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static
2803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultName[] = "not-initialized";
2903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
3010b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// The minimum number of advertising instances required for multi-advertisement
3110b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// support.
3210b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray//
3310b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// TODO(armansito): This number comes straight from
3410b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
3510b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// nice to know if there were a way to obtain this number from the stack instead
3610b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// of hardcoding it here.
3710b54c4b7f1a863a27eca4158f256062ec9c3770Arman Ugurayconst char kMinAdvInstancesForMultiAdv = 5;
3810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray
394cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
404cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray                                              AdapterState prev_state,
414cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray                                              AdapterState new_state) {
424cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  // Default implementation does nothing
434cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray}
444cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
4503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman UgurayAdapter::Adapter()
4603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    : state_(ADAPTER_STATE_OFF),
4703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      address_(kDefaultAddress),
4803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      name_(kDefaultName) {
4910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray  memset(&local_le_features_, 0, sizeof(local_le_features_));
504fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  hal::BluetoothInterface::Get()->AddObserver(this);
51c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray  ble_client_factory_.reset(new LowEnergyClientFactory());
5250a31545d2d20d92d161c51195b653eafd164025Arman Uguray  gatt_client_factory_.reset(new GattClientFactory());
530f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray  gatt_server_factory_.reset(new GattServerFactory());
542117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
554fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
564fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
574fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman UgurayAdapter::~Adapter() {
584fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  hal::BluetoothInterface::Get()->RemoveObserver(this);
594fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
604fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
614cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::AddObserver(Observer* observer) {
624cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  std::lock_guard<std::mutex> lock(observers_lock_);
634cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  observers_.AddObserver(observer);
644cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray}
654cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
664cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::RemoveObserver(Observer* observer) {
674cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  std::lock_guard<std::mutex> lock(observers_lock_);
684cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  observers_.RemoveObserver(observer);
694cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray}
704cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
712117e520c9f5b105ade7e92c4ab4928ea905f176Arman UgurayAdapterState Adapter::GetState() const {
722117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  return state_.load();
732117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray}
742117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
752117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguraybool Adapter::IsEnabled() const {
762117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  return state_.load() == ADAPTER_STATE_ON;
774fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
784fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
794fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::Enable() {
802117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  AdapterState current_state = GetState();
812117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  if (current_state != ADAPTER_STATE_OFF) {
822117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    LOG(INFO) << "Adapter not disabled - state: "
832117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray              << AdapterStateToString(current_state);
844fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    return false;
854fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
864fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
872117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  // Set the state before calling enable() as there might be a race between here
882117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  // and the AdapterStateChangedCallback.
892117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  state_ = ADAPTER_STATE_TURNING_ON;
904cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  NotifyAdapterStateChanged(current_state, state_);
912117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
924fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
934fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  if (status != BT_STATUS_SUCCESS) {
944fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    LOG(ERROR) << "Failed to enable Bluetooth - status: "
954fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray               << BtStatusText((const bt_status_t)status);
962117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    state_ = ADAPTER_STATE_OFF;
974cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray    NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
984fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    return false;
994fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1004fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1014fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  return true;
1024fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
1034fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1044fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::Disable() {
1052117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  if (!IsEnabled()) {
1062117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    LOG(INFO) << "Adapter is not enabled";
1074fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    return false;
1084fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1094fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1102117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  AdapterState current_state = GetState();
1112117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
1122117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  // Set the state before calling enable() as there might be a race between here
1132117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  // and the AdapterStateChangedCallback.
1142117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray  state_ = ADAPTER_STATE_TURNING_OFF;
1154cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  NotifyAdapterStateChanged(current_state, state_);
1162117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
1174fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
1184fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  if (status != BT_STATUS_SUCCESS) {
1194fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    LOG(ERROR) << "Failed to disable Bluetooth - status: "
1204fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray               << BtStatusText((const bt_status_t)status);
1212117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    state_ = current_state;
1224cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray    NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
1234fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    return false;
1244fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1254fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1264fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  return true;
1274fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
1284fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
12903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguraystd::string Adapter::GetName() const {
13003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  return name_.Get();
13103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray}
13203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
1334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::SetName(const std::string& name) {
1344fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  bt_bdname_t hal_name;
1354fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  size_t max_name_len = sizeof(hal_name.name);
1364fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1374fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  // Include the \0 byte in size measurement.
1384fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  if (name.length() >= max_name_len) {
1394fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum allowed"
1404fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray               << " size: " << max_name_len;
1414fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    return false;
1424fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1434fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1444fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
1454fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray          name.length() + 1);
1464fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1474fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  VLOG(1) << "Setting adapter name: " << name;
1484fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1494fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
1504fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    LOG(ERROR) << "Failed to set adapter name: " << name;
1514fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    return false;
1524fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1534fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1544fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  return true;
1554fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
1564fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
15703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguraystd::string Adapter::GetAddress() const {
15803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  return address_.Get();
15903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray}
16003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
16110b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguraybool Adapter::IsMultiAdvertisementSupported() const {
16210b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray  return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
16310b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray}
16410b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray
165c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman UgurayLowEnergyClientFactory* Adapter::GetLowEnergyClientFactory() const {
166c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray  return ble_client_factory_.get();
167c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray}
168c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray
16950a31545d2d20d92d161c51195b653eafd164025Arman UgurayGattClientFactory* Adapter::GetGattClientFactory() const {
17050a31545d2d20d92d161c51195b653eafd164025Arman Uguray  return gatt_client_factory_.get();
17150a31545d2d20d92d161c51195b653eafd164025Arman Uguray}
17250a31545d2d20d92d161c51195b653eafd164025Arman Uguray
1730f2d4897046f037a9f181f47f3d349a9dd646478Arman UgurayGattServerFactory* Adapter::GetGattServerFactory() const {
1740f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray  return gatt_server_factory_.get();
1750f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray}
1760f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray
1774fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Ugurayvoid Adapter::AdapterStateChangedCallback(bt_state_t state) {
1784fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  LOG(INFO) << "Adapter state changed: " << BtStateText(state);
1794fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1804cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  AdapterState prev_state = GetState();
1814cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
1824fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  switch (state) {
1834fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  case BT_STATE_OFF:
1842117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    state_ = ADAPTER_STATE_OFF;
1854fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    break;
1864fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1874fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  case BT_STATE_ON:
1882117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray    state_ = ADAPTER_STATE_ON;
1894fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    break;
1904fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1914fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  default:
1924fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    NOTREACHED();
1934fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1942117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
1954cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  NotifyAdapterStateChanged(prev_state, GetState());
1964fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
1974fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
19803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayvoid Adapter::AdapterPropertiesCallback(bt_status_t status,
19903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray                                        int num_properties,
20003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray                                        bt_property_t* properties) {
20103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  LOG(INFO) << "Adapter properties changed";
20203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
20303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  if (status != BT_STATUS_SUCCESS) {
20403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    LOG(ERROR) << "status: " << BtStatusText(status);
20503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    return;
20603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  }
20703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
20803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  for (int i = 0; i < num_properties; i++) {
20903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    bt_property_t* property = properties + i;
21003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    switch (property->type) {
21103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      case BT_PROPERTY_BDADDR: {
21203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>(
21303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray            property->val));
21403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        LOG(INFO) << "Adapter address changed: " << address;
21503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        address_.Set(address);
21603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        break;
21703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      }
21803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      case BT_PROPERTY_BDNAME: {
21903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
22003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        std::string name = reinterpret_cast<char*>(hal_name->name);
22103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        LOG(INFO) << "Adapter name changed: " << name;
22203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        name_.Set(name);
22303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        break;
22403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      }
22510b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray      case BT_PROPERTY_LOCAL_LE_FEATURES: {
22610b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray        if (property->len != sizeof(bt_local_le_features_t)) {
22710b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray          LOG(WARNING) << "Malformed value received for property: "
22810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray                       << "BT_PROPERTY_LOCAL_LE_FEATURES";
22910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray          break;
23010b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray        }
23110b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray        bt_local_le_features_t* features =
23210b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray            reinterpret_cast<bt_local_le_features_t*>(property->val);
23310b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray        memcpy(&local_le_features_, features, sizeof(*features));
23410b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray        LOG(INFO) << "Supported LE features updated";
23510b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray        break;
23610b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray      }
23703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      default:
23803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        VLOG(1) << "Unhandled adapter property: "
23903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray                << BtPropertyText(property->type);
24003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray        break;
24103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    }
24203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
24303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    // TODO(armansito): notify others of the updated properties
24403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  }
2454fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
2464fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2474fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraybool Adapter::SetAdapterProperty(bt_property_type_t type,
2484fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray                                 void* value, int length) {
2494fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  CHECK(length > 0);
2504fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  CHECK(value);
2514fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2524fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  bt_property_t property;
2534fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  property.len = length;
2544fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  property.val = value;
2554fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  property.type = type;
2564fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2574fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  int status = hal::BluetoothInterface::Get()->GetHALInterface()->
2584fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray      set_adapter_property(&property);
2594fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  if (status != BT_STATUS_SUCCESS) {
2604fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    VLOG(1) << "Failed to set property";
2614fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray    return false;
2624fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
2634fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2644fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  return true;
2654fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}
2664fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2674cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::NotifyAdapterStateChanged(AdapterState prev_state,
2684cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray                                        AdapterState new_state) {
2694cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  if (prev_state == new_state)
2704cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray    return;
2714cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
2724cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  std::lock_guard<std::mutex> lock(observers_lock_);
2734cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  FOR_EACH_OBSERVER(Observer, observers_,
2744cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray                    OnAdapterStateChanged(this, prev_state, new_state));
2754cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray}
2764cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
2774fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}  // namespace bluetooth
278