1// 2// Copyright (C) 2015 Google, Inc. 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at: 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "service/hal/bluetooth_interface.h" 18 19#include <mutex> 20#define _LIBCPP_BUILDING_SHARED_MUTEX 21#include <shared_mutex> 22#undef _LIBCPP_BUILDING_SHARED_MUTEX 23 24#include <base/logging.h> 25#include <base/observer_list.h> 26 27#include "service/logging_helpers.h" 28 29extern "C" { 30#include "btcore/include/hal_util.h" 31} // extern "C" 32 33using std::lock_guard; 34using std::unique_lock; 35using std::shared_lock; 36using std::mutex; 37using std::shared_timed_mutex; 38 39namespace bluetooth { 40namespace hal { 41 42namespace { 43 44// The global BluetoothInterface instance. 45BluetoothInterface* g_bluetooth_interface = nullptr; 46 47// Mutex used by callbacks to access |g_interface|. If we initialize or clean it 48// use unique_lock. If only accessing |g_interface| use shared lock. 49//TODO(jpawlowski): this should be just shared_mutex, as we currently don't use 50// timed methods. Change to shared_mutex when we upgrade to C++14 51shared_timed_mutex g_instance_lock; 52 53// Helper for obtaining the observer list. This is forward declared here and 54// defined below since it depends on BluetoothInterfaceImpl. 55base::ObserverList<BluetoothInterface::Observer>* GetObservers(); 56 57#define FOR_EACH_BLUETOOTH_OBSERVER(func) \ 58 FOR_EACH_OBSERVER(BluetoothInterface::Observer, *GetObservers(), func) 59 60#define VERIFY_INTERFACE_OR_RETURN() \ 61 do { \ 62 if (!g_bluetooth_interface) { \ 63 LOG(WARNING) << "Callback received while |g_interface| is NULL"; \ 64 return; \ 65 } \ 66 } while (0) 67 68void AdapterStateChangedCallback(bt_state_t state) { 69 shared_lock<shared_timed_mutex> lock(g_instance_lock); 70 VERIFY_INTERFACE_OR_RETURN(); 71 VLOG(1) << "Adapter state changed: " << BtStateText(state); 72 FOR_EACH_BLUETOOTH_OBSERVER(AdapterStateChangedCallback(state)); 73} 74 75void AdapterPropertiesCallback(bt_status_t status, 76 int num_properties, 77 bt_property_t* properties) { 78 shared_lock<shared_timed_mutex> lock(g_instance_lock); 79 VERIFY_INTERFACE_OR_RETURN(); 80 VLOG(1) << "Adapter properties changed - status: " << BtStatusText(status) 81 << ", num_properties: " << num_properties; 82 FOR_EACH_BLUETOOTH_OBSERVER( 83 AdapterPropertiesCallback(status, num_properties, properties)); 84} 85 86void RemoteDevicePropertiesCallback(bt_status_t status, 87 bt_bdaddr_t *remote_bd_addr, 88 int num_properties, 89 bt_property_t* properties) { 90 shared_lock<shared_timed_mutex> lock(g_instance_lock); 91 VERIFY_INTERFACE_OR_RETURN(); 92 VLOG(1) << " Remote device properties changed - status: " << BtStatusText(status) 93 << " - BD_ADDR: " << BtAddrString(remote_bd_addr) 94 << ", num_properties: " << num_properties; 95 FOR_EACH_BLUETOOTH_OBSERVER( 96 RemoteDevicePropertiesCallback(status, remote_bd_addr, num_properties, 97 properties)); 98} 99 100void DiscoveryStateChangedCallback(bt_discovery_state_t state) { 101 shared_lock<shared_timed_mutex> lock(g_instance_lock); 102 VERIFY_INTERFACE_OR_RETURN(); 103 VLOG(1) << "Discovery state changed - state: " << BtDiscoveryStateText(state); 104 FOR_EACH_BLUETOOTH_OBSERVER(DiscoveryStateChangedCallback(state)); 105} 106 107void PinRequestCallback(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name, 108 uint32_t cod, bool min_16_digit) { 109 shared_lock<shared_timed_mutex> lock(g_instance_lock); 110 VERIFY_INTERFACE_OR_RETURN(); 111 VLOG(2) << __func__ 112 << " - remote_bd_addr: " << remote_bd_addr 113 << " - bd_name: " << bd_name 114 << " - cod: " << cod 115 << " - min_16_digit: " << min_16_digit; 116 FOR_EACH_BLUETOOTH_OBSERVER(PinRequestCallback(remote_bd_addr, bd_name, cod, min_16_digit)); 117} 118 119void SSPRequestCallback(bt_bdaddr_t *remote_bd_addr, 120 bt_bdname_t *bd_name, uint32_t cod, bt_ssp_variant_t pairing_variant, uint32_t pass_key) { 121 shared_lock<shared_timed_mutex> lock(g_instance_lock); 122 VERIFY_INTERFACE_OR_RETURN(); 123 VLOG(2) << __func__ 124 << " - remote_bd_addr: " << remote_bd_addr 125 << " - bd_name: " << bd_name 126 << " - cod: " << cod 127 << " - pairing_variant: " << pairing_variant; 128 FOR_EACH_BLUETOOTH_OBSERVER(SSPRequestCallback(remote_bd_addr, bd_name, cod, 129 pairing_variant, pass_key)); 130} 131 132void BondStateChangedCallback( 133 bt_status_t status, 134 bt_bdaddr_t *remote_bd_addr, 135 bt_bond_state_t state) { 136 shared_lock<shared_timed_mutex> lock(g_instance_lock); 137 VERIFY_INTERFACE_OR_RETURN(); 138 VLOG(2) << __func__ 139 << " - remote_bd_addr: " << BtAddrString(remote_bd_addr) 140 << " - status: " << status 141 << " - state: " << state; 142 FOR_EACH_BLUETOOTH_OBSERVER(BondStateChangedCallback(status, remote_bd_addr, state)); 143} 144 145void AclStateChangedCallback(bt_status_t status, 146 bt_bdaddr_t *remote_bd_addr, 147 bt_acl_state_t state) { 148 shared_lock<shared_timed_mutex> lock(g_instance_lock); 149 VERIFY_INTERFACE_OR_RETURN(); 150 CHECK(remote_bd_addr); 151 VLOG(1) << "Remote device ACL state changed - status: " 152 << BtStatusText(status) 153 << " - BD_ADDR: " << BtAddrString(remote_bd_addr) 154 << " - state: " 155 << ((state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED"); 156 FOR_EACH_BLUETOOTH_OBSERVER( 157 AclStateChangedCallback(status, *remote_bd_addr, state)); 158} 159 160void ThreadEventCallback(bt_cb_thread_evt evt) { 161 VLOG(1) << "ThreadEventCallback" << BtEventText(evt); 162 163 // TODO(armansito): This callback is completely useless to us but btif borks 164 // out if this is not set. Consider making this optional. 165} 166 167bool SetWakeAlarmCallout(uint64_t /* delay_millis */, 168 bool /* should_wake */, 169 alarm_cb /* cb */, 170 void* /* data */) { 171 // TODO(armansito): According to sharvil@, this interface doesn't even need to 172 // exist and can be done entirely from within osi by interfacing directly with 173 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 174 return false; 175} 176 177int AcquireWakeLockCallout(const char* /* lock_name */) { 178 // TODO(armansito): According to sharvil@, this interface doesn't even need to 179 // exist and can be done entirely from within osi by interfacing directly with 180 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 181 // Lie here and return success so that enabling and disabling the controller 182 // works before this is properly implemented. 183 return BT_STATUS_SUCCESS; 184} 185 186int ReleaseWakeLockCallout(const char* /* lock_name */) { 187 // TODO(armansito): According to sharvil@, this interface doesn't even need to 188 // exist and can be done entirely from within osi by interfacing directly with 189 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 190 // Lie here and return success so that enabling and disabling the controller 191 // works before this is properly implemented. 192 return BT_STATUS_SUCCESS; 193} 194 195// The HAL Bluetooth DM callbacks. 196bt_callbacks_t bt_callbacks = { 197 sizeof(bt_callbacks_t), 198 AdapterStateChangedCallback, 199 AdapterPropertiesCallback, 200 RemoteDevicePropertiesCallback, 201 nullptr, /* device_found_cb */ 202 DiscoveryStateChangedCallback, 203 PinRequestCallback, 204 SSPRequestCallback, 205 BondStateChangedCallback, 206 AclStateChangedCallback, 207 ThreadEventCallback, 208 nullptr, /* dut_mode_recv_cb */ 209 nullptr, /* le_test_mode_cb */ 210 nullptr /* energy_info_cb */ 211}; 212 213bt_os_callouts_t bt_os_callouts = { 214 sizeof(bt_os_callouts_t), 215 SetWakeAlarmCallout, 216 AcquireWakeLockCallout, 217 ReleaseWakeLockCallout 218}; 219 220} // namespace 221 222// BluetoothInterface implementation for production. 223class BluetoothInterfaceImpl : public BluetoothInterface { 224 public: 225 BluetoothInterfaceImpl() 226 : hal_iface_(nullptr), 227 hal_adapter_(nullptr) { 228 } 229 230 ~BluetoothInterfaceImpl() override { 231 if (hal_iface_) 232 hal_iface_->cleanup(); 233 } 234 235 // BluetoothInterface overrides. 236 void AddObserver(Observer* observer) override { 237 shared_lock<shared_timed_mutex> lock(g_instance_lock); 238 observers_.AddObserver(observer); 239 } 240 241 void RemoveObserver(Observer* observer) override { 242 shared_lock<shared_timed_mutex> lock(g_instance_lock); 243 observers_.RemoveObserver(observer); 244 } 245 246 const bt_interface_t* GetHALInterface() const override { 247 return hal_iface_; 248 } 249 250 const bluetooth_device_t* GetHALAdapter() const override { 251 return hal_adapter_; 252 } 253 254 // Initialize the interface. This loads the shared Bluetooth library and sets 255 // up the callbacks. 256 bool Initialize() { 257 // Load the Bluetooth shared library module. 258 const hw_module_t* module; 259 int status = hal_util_load_bt_library(&module); 260 if (status) { 261 LOG(ERROR) << "Failed to load Bluetooth library: " << status; 262 return false; 263 } 264 265 // Open the Bluetooth adapter. 266 hw_device_t* device; 267 status = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device); 268 if (status) { 269 LOG(ERROR) << "Failed to open the Bluetooth module"; 270 return false; 271 } 272 273 hal_adapter_ = reinterpret_cast<bluetooth_device_t*>(device); 274 hal_iface_ = hal_adapter_->get_bluetooth_interface(); 275 276 // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API 277 // callbacks. 278 status = hal_iface_->init(&bt_callbacks); 279 if (status != BT_STATUS_SUCCESS) { 280 LOG(ERROR) << "Failed to initialize Bluetooth stack"; 281 return false; 282 } 283 284 status = hal_iface_->set_os_callouts(&bt_os_callouts); 285 if (status != BT_STATUS_SUCCESS) { 286 LOG(ERROR) << "Failed to set up Bluetooth OS callouts"; 287 return false; 288 } 289 290 return true; 291 } 292 293 base::ObserverList<Observer>* observers() { return &observers_; } 294 295 private: 296 // List of observers that are interested in notifications from us. We're not 297 // using a base::ObserverListThreadSafe, which it posts observer events 298 // automatically on the origin threads, as we want to avoid that overhead and 299 // simply forward the events to the upper layer. 300 base::ObserverList<Observer> observers_; 301 302 // The HAL handle obtained from the shared library. We hold a weak reference 303 // to this since the actual data resides in the shared Bluetooth library. 304 const bt_interface_t* hal_iface_; 305 306 // The HAL handle that represents the underlying Bluetooth adapter. We hold a 307 // weak reference to this since the actual data resides in the shared 308 // Bluetooth library. 309 const bluetooth_device_t* hal_adapter_; 310 311 DISALLOW_COPY_AND_ASSIGN(BluetoothInterfaceImpl); 312}; 313 314namespace { 315 316// Helper for obtaining the observer list from the global instance. This 317// function is NOT thread safe. 318base::ObserverList<BluetoothInterface::Observer>* GetObservers() { 319 CHECK(g_bluetooth_interface); 320 return static_cast<BluetoothInterfaceImpl*>( 321 g_bluetooth_interface)->observers(); 322} 323 324} // namespace 325 326// Default observer implementations. These are provided so that the methods 327// themselves are optional. 328void BluetoothInterface::Observer::AdapterStateChangedCallback( 329 bt_state_t /* state*/) { 330 // Do nothing. 331} 332 333void BluetoothInterface::Observer::AdapterPropertiesCallback( 334 bt_status_t /* status */, 335 int /* num_properties */, 336 bt_property_t* /* properties */) { 337 // Do nothing. 338} 339 340void BluetoothInterface::Observer::RemoteDevicePropertiesCallback( 341 bt_status_t /* status */, 342 bt_bdaddr_t* /* remote_bd_addr */, 343 int /* num_properties */, 344 bt_property_t* /* properties */) { 345 // Do nothing. 346} 347 348void BluetoothInterface::Observer::DiscoveryStateChangedCallback( 349 bt_discovery_state_t /* state */) { 350 // Do nothing. 351} 352 353void BluetoothInterface::Observer::PinRequestCallback( 354 bt_bdaddr_t *remote_bd_addr, 355 bt_bdname_t *bd_name, 356 uint32_t cod, 357 bool min_16_digit) { 358 // Do nothing. 359} 360 361void BluetoothInterface::Observer::SSPRequestCallback( 362 bt_bdaddr_t *remote_bd_addr, 363 bt_bdname_t *bd_name, 364 uint32_t cod, 365 bt_ssp_variant_t pairing_variant, 366 uint32_t pass_key) { 367 // Do nothing. 368} 369 370void BluetoothInterface::Observer::BondStateChangedCallback( 371 bt_status_t status, 372 bt_bdaddr_t *remote_bd_addr, 373 bt_bond_state_t state) { 374 // Do nothing. 375} 376 377void BluetoothInterface::Observer::AclStateChangedCallback( 378 bt_status_t /* status */, 379 const bt_bdaddr_t& /* remote_bdaddr */, 380 bt_acl_state_t /* state */) { 381 // Do nothing. 382} 383 384// static 385bool BluetoothInterface::Initialize() { 386 unique_lock<shared_timed_mutex> lock(g_instance_lock); 387 CHECK(!g_bluetooth_interface); 388 389 std::unique_ptr<BluetoothInterfaceImpl> impl(new BluetoothInterfaceImpl()); 390 if (!impl->Initialize()) { 391 LOG(ERROR) << "Failed to initialize BluetoothInterface"; 392 return false; 393 } 394 395 g_bluetooth_interface = impl.release(); 396 397 return true; 398} 399 400// static 401void BluetoothInterface::CleanUp() { 402 unique_lock<shared_timed_mutex> lock(g_instance_lock); 403 CHECK(g_bluetooth_interface); 404 405 delete g_bluetooth_interface; 406 g_bluetooth_interface = nullptr; 407} 408 409// static 410bool BluetoothInterface::IsInitialized() { 411 shared_lock<shared_timed_mutex> lock(g_instance_lock); 412 413 return g_bluetooth_interface != nullptr; 414} 415 416// static 417BluetoothInterface* BluetoothInterface::Get() { 418 shared_lock<shared_timed_mutex> lock(g_instance_lock); 419 CHECK(g_bluetooth_interface); 420 return g_bluetooth_interface; 421} 422 423// static 424void BluetoothInterface::InitializeForTesting( 425 BluetoothInterface* test_instance) { 426 unique_lock<shared_timed_mutex> lock(g_instance_lock); 427 CHECK(test_instance); 428 CHECK(!g_bluetooth_interface); 429 430 g_bluetooth_interface = test_instance; 431} 432 433} // namespace hal 434} // namespace bluetooth 435