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 #include <shared_mutex> 21 22 #include <base/logging.h> 23 #include <base/observer_list.h> 24 25 #include "service/logging_helpers.h" 26 27 #include "btcore/include/hal_util.h" 28 29 using std::lock_guard; 30 using std::unique_lock; 31 using std::shared_lock; 32 using std::mutex; 33 #if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500) 34 using shared_mutex_impl = std::shared_mutex; 35 #else 36 using shared_mutex_impl = std::shared_timed_mutex; 37 #endif 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_mutex_impl 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_mutex_impl> 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, int num_properties, 76 bt_property_t* properties) { 77 shared_lock<shared_mutex_impl> lock(g_instance_lock); 78 VERIFY_INTERFACE_OR_RETURN(); 79 VLOG(1) << "Adapter properties changed - status: " << BtStatusText(status) 80 << ", num_properties: " << num_properties; 81 FOR_EACH_BLUETOOTH_OBSERVER( 82 AdapterPropertiesCallback(status, num_properties, properties)); 83 } 84 85 void RemoteDevicePropertiesCallback(bt_status_t status, 86 bt_bdaddr_t* remote_bd_addr, 87 int num_properties, 88 bt_property_t* properties) { 89 shared_lock<shared_mutex_impl> lock(g_instance_lock); 90 VERIFY_INTERFACE_OR_RETURN(); 91 VLOG(1) << " Remote device properties changed - status: " 92 << BtStatusText(status) 93 << " - BD_ADDR: " << BtAddrString(remote_bd_addr) 94 << ", num_properties: " << num_properties; 95 FOR_EACH_BLUETOOTH_OBSERVER(RemoteDevicePropertiesCallback( 96 status, remote_bd_addr, num_properties, properties)); 97 } 98 99 void DiscoveryStateChangedCallback(bt_discovery_state_t state) { 100 shared_lock<shared_mutex_impl> lock(g_instance_lock); 101 VERIFY_INTERFACE_OR_RETURN(); 102 VLOG(1) << "Discovery state changed - state: " << BtDiscoveryStateText(state); 103 FOR_EACH_BLUETOOTH_OBSERVER(DiscoveryStateChangedCallback(state)); 104 } 105 106 void PinRequestCallback(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, 107 uint32_t cod, bool min_16_digit) { 108 shared_lock<shared_mutex_impl> lock(g_instance_lock); 109 VERIFY_INTERFACE_OR_RETURN(); 110 VLOG(2) << __func__ << " - remote_bd_addr: " << remote_bd_addr 111 << " - bd_name: " << bd_name << " - cod: " << cod 112 << " - min_16_digit: " << min_16_digit; 113 FOR_EACH_BLUETOOTH_OBSERVER( 114 PinRequestCallback(remote_bd_addr, bd_name, cod, min_16_digit)); 115 } 116 117 void SSPRequestCallback(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, 118 uint32_t cod, bt_ssp_variant_t pairing_variant, 119 uint32_t pass_key) { 120 shared_lock<shared_mutex_impl> lock(g_instance_lock); 121 VERIFY_INTERFACE_OR_RETURN(); 122 VLOG(2) << __func__ << " - remote_bd_addr: " << remote_bd_addr 123 << " - bd_name: " << bd_name << " - cod: " << cod 124 << " - pairing_variant: " << pairing_variant; 125 FOR_EACH_BLUETOOTH_OBSERVER(SSPRequestCallback(remote_bd_addr, bd_name, cod, 126 pairing_variant, pass_key)); 127 } 128 129 void BondStateChangedCallback(bt_status_t status, bt_bdaddr_t* remote_bd_addr, 130 bt_bond_state_t state) { 131 shared_lock<shared_mutex_impl> lock(g_instance_lock); 132 VERIFY_INTERFACE_OR_RETURN(); 133 VLOG(2) << __func__ << " - remote_bd_addr: " << BtAddrString(remote_bd_addr) 134 << " - status: " << status << " - state: " << state; 135 FOR_EACH_BLUETOOTH_OBSERVER( 136 BondStateChangedCallback(status, remote_bd_addr, state)); 137 } 138 139 void AclStateChangedCallback(bt_status_t status, bt_bdaddr_t* remote_bd_addr, 140 bt_acl_state_t state) { 141 shared_lock<shared_mutex_impl> lock(g_instance_lock); 142 VERIFY_INTERFACE_OR_RETURN(); 143 CHECK(remote_bd_addr); 144 VLOG(1) << "Remote device ACL state changed - status: " 145 << BtStatusText(status) 146 << " - BD_ADDR: " << BtAddrString(remote_bd_addr) << " - state: " 147 << ((state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED"); 148 FOR_EACH_BLUETOOTH_OBSERVER( 149 AclStateChangedCallback(status, *remote_bd_addr, state)); 150 } 151 152 void ThreadEventCallback(bt_cb_thread_evt evt) { 153 VLOG(1) << "ThreadEventCallback" << BtEventText(evt); 154 155 // TODO(armansito): This callback is completely useless to us but btif borks 156 // out if this is not set. Consider making this optional. 157 } 158 159 bool SetWakeAlarmCallout(uint64_t /* delay_millis */, bool /* should_wake */, 160 alarm_cb /* cb */, void* /* data */) { 161 // TODO(armansito): According to sharvil@, this interface doesn't even need to 162 // exist and can be done entirely from within osi by interfacing directly with 163 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 164 return false; 165 } 166 167 int AcquireWakeLockCallout(const char* /* lock_name */) { 168 // TODO(armansito): According to sharvil@, this interface doesn't even need to 169 // exist and can be done entirely from within osi by interfacing directly with 170 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 171 // Lie here and return success so that enabling and disabling the controller 172 // works before this is properly implemented. 173 return BT_STATUS_SUCCESS; 174 } 175 176 int ReleaseWakeLockCallout(const char* /* lock_name */) { 177 // TODO(armansito): According to sharvil@, this interface doesn't even need to 178 // exist and can be done entirely from within osi by interfacing directly with 179 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 180 // Lie here and return success so that enabling and disabling the controller 181 // works before this is properly implemented. 182 return BT_STATUS_SUCCESS; 183 } 184 185 // The HAL Bluetooth DM callbacks. 186 bt_callbacks_t bt_callbacks = { 187 sizeof(bt_callbacks_t), 188 AdapterStateChangedCallback, 189 AdapterPropertiesCallback, 190 RemoteDevicePropertiesCallback, 191 nullptr, /* device_found_cb */ 192 DiscoveryStateChangedCallback, 193 PinRequestCallback, 194 SSPRequestCallback, 195 BondStateChangedCallback, 196 AclStateChangedCallback, 197 ThreadEventCallback, 198 nullptr, /* dut_mode_recv_cb */ 199 nullptr, /* le_test_mode_cb */ 200 nullptr /* energy_info_cb */ 201 }; 202 203 bt_os_callouts_t bt_os_callouts = {sizeof(bt_os_callouts_t), 204 SetWakeAlarmCallout, AcquireWakeLockCallout, 205 ReleaseWakeLockCallout}; 206 207 } // namespace 208 209 // BluetoothInterface implementation for production. 210 class BluetoothInterfaceImpl : public BluetoothInterface { 211 public: 212 BluetoothInterfaceImpl() : hal_iface_(nullptr), hal_adapter_(nullptr) {} 213 214 ~BluetoothInterfaceImpl() override { 215 if (hal_iface_) hal_iface_->cleanup(); 216 } 217 218 // BluetoothInterface overrides. 219 void AddObserver(Observer* observer) override { 220 shared_lock<shared_mutex_impl> lock(g_instance_lock); 221 observers_.AddObserver(observer); 222 } 223 224 void RemoveObserver(Observer* observer) override { 225 shared_lock<shared_mutex_impl> lock(g_instance_lock); 226 observers_.RemoveObserver(observer); 227 } 228 229 const bt_interface_t* GetHALInterface() const override { return hal_iface_; } 230 231 bt_callbacks_t* GetHALCallbacks() const override { return &bt_callbacks; } 232 233 const bluetooth_device_t* GetHALAdapter() const override { 234 return hal_adapter_; 235 } 236 237 // Initialize the interface. This loads the shared Bluetooth library and sets 238 // up the callbacks. 239 bool Initialize() { 240 // Load the Bluetooth shared library module. 241 const hw_module_t* module; 242 int status = hal_util_load_bt_library(&module); 243 if (status) { 244 LOG(ERROR) << "Failed to load Bluetooth library: " << status; 245 return false; 246 } 247 248 // Open the Bluetooth adapter. 249 hw_device_t* device; 250 status = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device); 251 if (status) { 252 LOG(ERROR) << "Failed to open the Bluetooth module"; 253 return false; 254 } 255 256 hal_adapter_ = reinterpret_cast<bluetooth_device_t*>(device); 257 hal_iface_ = hal_adapter_->get_bluetooth_interface(); 258 259 // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API 260 // callbacks. 261 status = hal_iface_->init(&bt_callbacks); 262 if (status != BT_STATUS_SUCCESS) { 263 LOG(ERROR) << "Failed to initialize Bluetooth stack"; 264 return false; 265 } 266 267 status = hal_iface_->set_os_callouts(&bt_os_callouts); 268 if (status != BT_STATUS_SUCCESS) { 269 LOG(ERROR) << "Failed to set up Bluetooth OS callouts"; 270 return false; 271 } 272 273 return true; 274 } 275 276 base::ObserverList<Observer>* observers() { return &observers_; } 277 278 private: 279 // List of observers that are interested in notifications from us. We're not 280 // using a base::ObserverListThreadSafe, which it posts observer events 281 // automatically on the origin threads, as we want to avoid that overhead and 282 // simply forward the events to the upper layer. 283 base::ObserverList<Observer> observers_; 284 285 // The HAL handle obtained from the shared library. We hold a weak reference 286 // to this since the actual data resides in the shared Bluetooth library. 287 const bt_interface_t* hal_iface_; 288 289 // The HAL handle that represents the underlying Bluetooth adapter. We hold a 290 // weak reference to this since the actual data resides in the shared 291 // Bluetooth library. 292 const bluetooth_device_t* hal_adapter_; 293 294 DISALLOW_COPY_AND_ASSIGN(BluetoothInterfaceImpl); 295 }; 296 297 namespace { 298 299 // Helper for obtaining the observer list from the global instance. This 300 // function is NOT thread safe. 301 base::ObserverList<BluetoothInterface::Observer>* GetObservers() { 302 CHECK(g_bluetooth_interface); 303 return static_cast<BluetoothInterfaceImpl*>(g_bluetooth_interface) 304 ->observers(); 305 } 306 307 } // namespace 308 309 // Default observer implementations. These are provided so that the methods 310 // themselves are optional. 311 void BluetoothInterface::Observer::AdapterStateChangedCallback( 312 bt_state_t /* state*/) { 313 // Do nothing. 314 } 315 316 void BluetoothInterface::Observer::AdapterPropertiesCallback( 317 bt_status_t /* status */, int /* num_properties */, 318 bt_property_t* /* properties */) { 319 // Do nothing. 320 } 321 322 void BluetoothInterface::Observer::RemoteDevicePropertiesCallback( 323 bt_status_t /* status */, bt_bdaddr_t* /* remote_bd_addr */, 324 int /* num_properties */, bt_property_t* /* properties */) { 325 // Do nothing. 326 } 327 328 void BluetoothInterface::Observer::DiscoveryStateChangedCallback( 329 bt_discovery_state_t /* state */) { 330 // Do nothing. 331 } 332 333 void BluetoothInterface::Observer::PinRequestCallback( 334 bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod, 335 bool min_16_digit) { 336 // Do nothing. 337 } 338 339 void BluetoothInterface::Observer::SSPRequestCallback( 340 bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod, 341 bt_ssp_variant_t pairing_variant, uint32_t pass_key) { 342 // Do nothing. 343 } 344 345 void BluetoothInterface::Observer::BondStateChangedCallback( 346 bt_status_t status, bt_bdaddr_t* remote_bd_addr, bt_bond_state_t state) { 347 // Do nothing. 348 } 349 350 void BluetoothInterface::Observer::AclStateChangedCallback( 351 bt_status_t /* status */, const bt_bdaddr_t& /* remote_bdaddr */, 352 bt_acl_state_t /* state */) { 353 // Do nothing. 354 } 355 356 // static 357 bool BluetoothInterface::Initialize() { 358 unique_lock<shared_mutex_impl> lock(g_instance_lock); 359 CHECK(!g_bluetooth_interface); 360 361 std::unique_ptr<BluetoothInterfaceImpl> impl(new BluetoothInterfaceImpl()); 362 if (!impl->Initialize()) { 363 LOG(ERROR) << "Failed to initialize BluetoothInterface"; 364 return false; 365 } 366 367 g_bluetooth_interface = impl.release(); 368 369 return true; 370 } 371 372 // static 373 void BluetoothInterface::CleanUp() { 374 unique_lock<shared_mutex_impl> lock(g_instance_lock); 375 CHECK(g_bluetooth_interface); 376 377 delete g_bluetooth_interface; 378 g_bluetooth_interface = nullptr; 379 } 380 381 // static 382 bool BluetoothInterface::IsInitialized() { 383 shared_lock<shared_mutex_impl> lock(g_instance_lock); 384 385 return g_bluetooth_interface != nullptr; 386 } 387 388 // static 389 BluetoothInterface* BluetoothInterface::Get() { 390 shared_lock<shared_mutex_impl> lock(g_instance_lock); 391 CHECK(g_bluetooth_interface); 392 return g_bluetooth_interface; 393 } 394 395 // static 396 void BluetoothInterface::InitializeForTesting( 397 BluetoothInterface* test_instance) { 398 unique_lock<shared_mutex_impl> lock(g_instance_lock); 399 CHECK(test_instance); 400 CHECK(!g_bluetooth_interface); 401 402 g_bluetooth_interface = test_instance; 403 } 404 405 } // namespace hal 406 } // namespace bluetooth 407