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 29 extern "C" { 30 #include "btcore/include/hal_util.h" 31 } // extern "C" 32 33 using std::lock_guard; 34 using std::unique_lock; 35 using std::shared_lock; 36 using std::mutex; 37 using std::shared_timed_mutex; 38 39 namespace bluetooth { 40 namespace hal { 41 42 namespace { 43 44 // The global BluetoothInterface instance. 45 BluetoothInterface* 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 51 shared_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. 55 base::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 68 void 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 75 void 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 86 void 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 100 void 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 107 void 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 119 void 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 132 void 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 145 void 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 160 void 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 167 bool 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 177 int 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 186 int 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. 196 bt_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 213 bt_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. 223 class 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 314 namespace { 315 316 // Helper for obtaining the observer list from the global instance. This 317 // function is NOT thread safe. 318 base::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. 328 void BluetoothInterface::Observer::AdapterStateChangedCallback( 329 bt_state_t /* state*/) { 330 // Do nothing. 331 } 332 333 void BluetoothInterface::Observer::AdapterPropertiesCallback( 334 bt_status_t /* status */, 335 int /* num_properties */, 336 bt_property_t* /* properties */) { 337 // Do nothing. 338 } 339 340 void 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 348 void BluetoothInterface::Observer::DiscoveryStateChangedCallback( 349 bt_discovery_state_t /* state */) { 350 // Do nothing. 351 } 352 353 void 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 361 void 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 370 void 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 377 void 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 385 bool 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 401 void 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 410 bool BluetoothInterface::IsInitialized() { 411 shared_lock<shared_timed_mutex> lock(g_instance_lock); 412 413 return g_bluetooth_interface != nullptr; 414 } 415 416 // static 417 BluetoothInterface* 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 424 void 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