12202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// 22202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// Copyright (C) 2015 Google, Inc. 32202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// 42202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// Licensed under the Apache License, Version 2.0 (the "License"); 52202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// you may not use this file except in compliance with the License. 62202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// You may obtain a copy of the License at: 72202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// 82202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// http://www.apache.org/licenses/LICENSE-2.0 92202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// 102202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// Unless required by applicable law or agreed to in writing, software 112202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// distributed under the License is distributed on an "AS IS" BASIS, 122202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// See the License for the specific language governing permissions and 142202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// limitations under the License. 152202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// 162202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 172202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include "service/hal/bluetooth_interface.h" 182202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 192202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include <mutex> 203c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski#include <shared_mutex> 212202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 222202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include <base/logging.h> 232202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include <base/observer_list.h> 242202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 252202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include "service/logging_helpers.h" 262202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 272202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include "btcore/include/hal_util.h" 282202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 292202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayusing std::lock_guard; 303c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowskiusing std::unique_lock; 313c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowskiusing std::shared_lock; 322202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayusing std::mutex; 331f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He#if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500) 341f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack Heusing shared_mutex_impl = std::shared_mutex; 351f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He#else 361f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack Heusing shared_mutex_impl = std::shared_timed_mutex; 371f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He#endif 382202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 392202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace bluetooth { 402202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace hal { 412202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 422202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace { 432202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 442202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// The global BluetoothInterface instance. 452202cd58a1c623224eae92969f8a0fc8dbd1c17bArman UgurayBluetoothInterface* g_bluetooth_interface = nullptr; 462202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 473c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski// Mutex used by callbacks to access |g_interface|. If we initialize or clean it 483c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski// use unique_lock. If only accessing |g_interface| use shared lock. 49911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson// TODO(jpawlowski): this should be just shared_mutex, as we currently don't use 503c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski// timed methods. Change to shared_mutex when we upgrade to C++14 511f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack Heshared_mutex_impl g_instance_lock; 522202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 532202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// Helper for obtaining the observer list. This is forward declared here and 542202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// defined below since it depends on BluetoothInterfaceImpl. 552202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybase::ObserverList<BluetoothInterface::Observer>* GetObservers(); 562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#define FOR_EACH_BLUETOOTH_OBSERVER(func) \ 582202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray FOR_EACH_OBSERVER(BluetoothInterface::Observer, *GetObservers(), func) 592202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define VERIFY_INTERFACE_OR_RETURN() \ 61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson do { \ 62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!g_bluetooth_interface) { \ 630f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray LOG(WARNING) << "Callback received while |g_interface| is NULL"; \ 64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return; \ 65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } \ 660f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray } while (0) 670f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 682202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid AdapterStateChangedCallback(bt_state_t state) { 691f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 700f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray VERIFY_INTERFACE_OR_RETURN(); 712202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray VLOG(1) << "Adapter state changed: " << BtStateText(state); 722202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray FOR_EACH_BLUETOOTH_OBSERVER(AdapterStateChangedCallback(state)); 732202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 742202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid AdapterPropertiesCallback(bt_status_t status, int num_properties, 762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray bt_property_t* properties) { 771f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 780f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray VERIFY_INTERFACE_OR_RETURN(); 792202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray VLOG(1) << "Adapter properties changed - status: " << BtStatusText(status) 802202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray << ", num_properties: " << num_properties; 812202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray FOR_EACH_BLUETOOTH_OBSERVER( 822202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray AdapterPropertiesCallback(status, num_properties, properties)); 832202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 842202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 85f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowskivoid RemoteDevicePropertiesCallback(bt_status_t status, 869e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski RawAddress* remote_bd_addr, 87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int num_properties, 88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_property_t* properties) { 891f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 90f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski VERIFY_INTERFACE_OR_RETURN(); 91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson VLOG(1) << " Remote device properties changed - status: " 92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson << BtStatusText(status) 93f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski << " - BD_ADDR: " << BtAddrString(remote_bd_addr) 94f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski << ", num_properties: " << num_properties; 95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson FOR_EACH_BLUETOOTH_OBSERVER(RemoteDevicePropertiesCallback( 96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status, remote_bd_addr, num_properties, properties)); 97f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski} 98f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski 99fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panickervoid DiscoveryStateChangedCallback(bt_discovery_state_t state) { 1001f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 1010f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray VERIFY_INTERFACE_OR_RETURN(); 102fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker VLOG(1) << "Discovery state changed - state: " << BtDiscoveryStateText(state); 103fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker FOR_EACH_BLUETOOTH_OBSERVER(DiscoveryStateChangedCallback(state)); 104fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker} 105fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker 1069e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid PinRequestCallback(RawAddress* remote_bd_addr, bt_bdname_t* bd_name, 107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint32_t cod, bool min_16_digit) { 1081f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 109c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski VERIFY_INTERFACE_OR_RETURN(); 110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson VLOG(2) << __func__ << " - remote_bd_addr: " << remote_bd_addr 111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson << " - bd_name: " << bd_name << " - cod: " << cod 112c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski << " - min_16_digit: " << min_16_digit; 113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson FOR_EACH_BLUETOOTH_OBSERVER( 114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson PinRequestCallback(remote_bd_addr, bd_name, cod, min_16_digit)); 115c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski} 116c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski 1179e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid SSPRequestCallback(RawAddress* remote_bd_addr, bt_bdname_t* bd_name, 118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint32_t cod, bt_ssp_variant_t pairing_variant, 119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint32_t pass_key) { 1201f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 121c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski VERIFY_INTERFACE_OR_RETURN(); 122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson VLOG(2) << __func__ << " - remote_bd_addr: " << remote_bd_addr 123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson << " - bd_name: " << bd_name << " - cod: " << cod 124c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski << " - pairing_variant: " << pairing_variant; 125c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski FOR_EACH_BLUETOOTH_OBSERVER(SSPRequestCallback(remote_bd_addr, bd_name, cod, 126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pairing_variant, pass_key)); 127c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski} 128c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski 1299e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid BondStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr, 130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_bond_state_t state) { 1311f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 132c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski VERIFY_INTERFACE_OR_RETURN(); 133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson VLOG(2) << __func__ << " - remote_bd_addr: " << BtAddrString(remote_bd_addr) 134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson << " - status: " << status << " - state: " << state; 135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson FOR_EACH_BLUETOOTH_OBSERVER( 136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BondStateChangedCallback(status, remote_bd_addr, state)); 137c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski} 138c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski 1399e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr, 1400f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray bt_acl_state_t state) { 1411f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 1420f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray VERIFY_INTERFACE_OR_RETURN(); 1430f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray CHECK(remote_bd_addr); 1440f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray VLOG(1) << "Remote device ACL state changed - status: " 1450f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray << BtStatusText(status) 146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson << " - BD_ADDR: " << BtAddrString(remote_bd_addr) << " - state: " 1470f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray << ((state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED"); 1480f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray FOR_EACH_BLUETOOTH_OBSERVER( 1490f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray AclStateChangedCallback(status, *remote_bd_addr, state)); 1500f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray} 1510f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 1522202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid ThreadEventCallback(bt_cb_thread_evt evt) { 1532202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray VLOG(1) << "ThreadEventCallback" << BtEventText(evt); 1542202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 1552202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // TODO(armansito): This callback is completely useless to us but btif borks 1562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // out if this is not set. Consider making this optional. 1572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 1582202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool SetWakeAlarmCallout(uint64_t /* delay_millis */, bool /* should_wake */, 160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson alarm_cb /* cb */, void* /* data */) { 161e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // TODO(armansito): According to sharvil@, this interface doesn't even need to 162e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // exist and can be done entirely from within osi by interfacing directly with 163e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 164e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray return false; 1652202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 1662202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 1672202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayint AcquireWakeLockCallout(const char* /* lock_name */) { 168e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // TODO(armansito): According to sharvil@, this interface doesn't even need to 169e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // exist and can be done entirely from within osi by interfacing directly with 170e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 171d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray // Lie here and return success so that enabling and disabling the controller 172d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray // works before this is properly implemented. 173d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray return BT_STATUS_SUCCESS; 1742202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 1752202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 1762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayint ReleaseWakeLockCallout(const char* /* lock_name */) { 177e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // TODO(armansito): According to sharvil@, this interface doesn't even need to 178e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // exist and can be done entirely from within osi by interfacing directly with 179e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray // the kernel. Remove these stubs once that's fixed. (See http://b/23390297) 180d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray // Lie here and return success so that enabling and disabling the controller 181d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray // works before this is properly implemented. 182d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray return BT_STATUS_SUCCESS; 1832202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 1842202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 1852202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// The HAL Bluetooth DM callbacks. 1862202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybt_callbacks_t bt_callbacks = { 187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson sizeof(bt_callbacks_t), 188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AdapterStateChangedCallback, 189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AdapterPropertiesCallback, 190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson RemoteDevicePropertiesCallback, 191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nullptr, /* device_found_cb */ 192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson DiscoveryStateChangedCallback, 193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson PinRequestCallback, 194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson SSPRequestCallback, 195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BondStateChangedCallback, 196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AclStateChangedCallback, 197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ThreadEventCallback, 198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nullptr, /* dut_mode_recv_cb */ 199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nullptr, /* le_test_mode_cb */ 200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nullptr /* energy_info_cb */ 2012202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}; 2022202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbt_os_callouts_t bt_os_callouts = {sizeof(bt_os_callouts_t), 204911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson SetWakeAlarmCallout, AcquireWakeLockCallout, 205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ReleaseWakeLockCallout}; 2062202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2072202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} // namespace 2082202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2092202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// BluetoothInterface implementation for production. 2102202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayclass BluetoothInterfaceImpl : public BluetoothInterface { 2112202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray public: 212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BluetoothInterfaceImpl() : hal_iface_(nullptr), hal_adapter_(nullptr) {} 2132202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2142202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray ~BluetoothInterfaceImpl() override { 215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (hal_iface_) hal_iface_->cleanup(); 21642c89a0e5f3e2771681ebd11281d6e3c20341894Ajay Panicker } 2172202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2182202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // BluetoothInterface overrides. 2192202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray void AddObserver(Observer* observer) override { 2201f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 2212202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray observers_.AddObserver(observer); 2222202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2232202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2242202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray void RemoveObserver(Observer* observer) override { 2251f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 2262202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray observers_.RemoveObserver(observer); 2272202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2282202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson const bt_interface_t* GetHALInterface() const override { return hal_iface_; } 2302202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 231a3292051d9c088769b0f4e46ffaf7c66b1127194Pavlin Radoslavov bt_callbacks_t* GetHALCallbacks() const override { return &bt_callbacks; } 232a3292051d9c088769b0f4e46ffaf7c66b1127194Pavlin Radoslavov 2332202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray const bluetooth_device_t* GetHALAdapter() const override { 2342202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return hal_adapter_; 2352202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2362202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2372202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // Initialize the interface. This loads the shared Bluetooth library and sets 2382202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // up the callbacks. 2392202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray bool Initialize() { 2402202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // Load the Bluetooth shared library module. 2412202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray const hw_module_t* module; 2422202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray int status = hal_util_load_bt_library(&module); 2432202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray if (status) { 24442c89a0e5f3e2771681ebd11281d6e3c20341894Ajay Panicker LOG(ERROR) << "Failed to load Bluetooth library: " << status; 2452202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return false; 2462202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2472202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2482202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // Open the Bluetooth adapter. 2492202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray hw_device_t* device; 2502202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray status = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device); 2512202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray if (status) { 2522202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray LOG(ERROR) << "Failed to open the Bluetooth module"; 2532202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return false; 2542202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2552202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray hal_adapter_ = reinterpret_cast<bluetooth_device_t*>(device); 2572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray hal_iface_ = hal_adapter_->get_bluetooth_interface(); 2582202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2592202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API 2602202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // callbacks. 2612202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray status = hal_iface_->init(&bt_callbacks); 2622202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray if (status != BT_STATUS_SUCCESS) { 2632202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray LOG(ERROR) << "Failed to initialize Bluetooth stack"; 2642202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return false; 2652202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2662202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2672202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray status = hal_iface_->set_os_callouts(&bt_os_callouts); 2682202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray if (status != BT_STATUS_SUCCESS) { 2692202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray LOG(ERROR) << "Failed to set up Bluetooth OS callouts"; 2702202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return false; 2712202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2722202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2732202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return true; 2742202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 2752202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray base::ObserverList<Observer>* observers() { return &observers_; } 2772202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2782202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray private: 2792202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // List of observers that are interested in notifications from us. We're not 2802202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // using a base::ObserverListThreadSafe, which it posts observer events 2812202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // automatically on the origin threads, as we want to avoid that overhead and 2822202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // simply forward the events to the upper layer. 2832202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray base::ObserverList<Observer> observers_; 2842202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2852202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // The HAL handle obtained from the shared library. We hold a weak reference 2862202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // to this since the actual data resides in the shared Bluetooth library. 2872202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray const bt_interface_t* hal_iface_; 2882202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2892202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // The HAL handle that represents the underlying Bluetooth adapter. We hold a 2902202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // weak reference to this since the actual data resides in the shared 2912202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray // Bluetooth library. 2922202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray const bluetooth_device_t* hal_adapter_; 2932202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2942202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray DISALLOW_COPY_AND_ASSIGN(BluetoothInterfaceImpl); 2952202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}; 2962202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2972202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace { 2982202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 2992202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// Helper for obtaining the observer list from the global instance. This 3002202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// function is NOT thread safe. 3012202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybase::ObserverList<BluetoothInterface::Observer>* GetObservers() { 3022202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray CHECK(g_bluetooth_interface); 303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return static_cast<BluetoothInterfaceImpl*>(g_bluetooth_interface) 304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ->observers(); 3052202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 3062202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3072202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} // namespace 3082202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 309c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker// Default observer implementations. These are provided so that the methods 310c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker// themselves are optional. 311c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panickervoid BluetoothInterface::Observer::AdapterStateChangedCallback( 312c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker bt_state_t /* state*/) { 313c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker // Do nothing. 314c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker} 315c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker 316c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panickervoid BluetoothInterface::Observer::AdapterPropertiesCallback( 317911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_status_t /* status */, int /* num_properties */, 318c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker bt_property_t* /* properties */) { 319c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker // Do nothing. 320c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker} 321c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker 322f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowskivoid BluetoothInterface::Observer::RemoteDevicePropertiesCallback( 3239e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski bt_status_t /* status */, RawAddress* /* remote_bd_addr */, 324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int /* num_properties */, bt_property_t* /* properties */) { 325f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski // Do nothing. 326f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski} 327f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski 328c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panickervoid BluetoothInterface::Observer::DiscoveryStateChangedCallback( 329c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker bt_discovery_state_t /* state */) { 330c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker // Do nothing. 331c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker} 332c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker 333c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowskivoid BluetoothInterface::Observer::PinRequestCallback( 3349e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod, 335c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski bool min_16_digit) { 336c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski // Do nothing. 337c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski} 338c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski 339c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowskivoid BluetoothInterface::Observer::SSPRequestCallback( 3409e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod, 341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_ssp_variant_t pairing_variant, uint32_t pass_key) { 342c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski // Do nothing. 343c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski} 344c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski 345c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowskivoid BluetoothInterface::Observer::BondStateChangedCallback( 3469e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski bt_status_t status, RawAddress* remote_bd_addr, bt_bond_state_t state) { 347c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski // Do nothing. 348c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski} 349c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski 3500f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Ugurayvoid BluetoothInterface::Observer::AclStateChangedCallback( 3519e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski bt_status_t /* status */, const RawAddress& /* remote_bdaddr */, 3520f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray bt_acl_state_t /* state */) { 3530f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray // Do nothing. 3540f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray} 3550f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray 3562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static 3572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybool BluetoothInterface::Initialize() { 3581f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He unique_lock<shared_mutex_impl> lock(g_instance_lock); 3592202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray CHECK(!g_bluetooth_interface); 3602202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3612202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray std::unique_ptr<BluetoothInterfaceImpl> impl(new BluetoothInterfaceImpl()); 3622202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray if (!impl->Initialize()) { 3632202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray LOG(ERROR) << "Failed to initialize BluetoothInterface"; 3642202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return false; 3652202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray } 3662202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3672202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray g_bluetooth_interface = impl.release(); 3682202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3692202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return true; 3702202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 3712202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3722202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static 3732202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid BluetoothInterface::CleanUp() { 3741f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He unique_lock<shared_mutex_impl> lock(g_instance_lock); 3752202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray CHECK(g_bluetooth_interface); 3762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3772202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray delete g_bluetooth_interface; 3782202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray g_bluetooth_interface = nullptr; 3792202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 3802202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3812202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static 3829ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguraybool BluetoothInterface::IsInitialized() { 3831f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 3849ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray 3859ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray return g_bluetooth_interface != nullptr; 3869ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray} 3879ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray 3889ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray// static 3892202cd58a1c623224eae92969f8a0fc8dbd1c17bArman UgurayBluetoothInterface* BluetoothInterface::Get() { 3901f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He shared_lock<shared_mutex_impl> lock(g_instance_lock); 3912202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray CHECK(g_bluetooth_interface); 3922202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray return g_bluetooth_interface; 3932202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 3942202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 3952202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static 3962202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid BluetoothInterface::InitializeForTesting( 3972202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray BluetoothInterface* test_instance) { 3981f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He unique_lock<shared_mutex_impl> lock(g_instance_lock); 3992202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray CHECK(test_instance); 4002202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray CHECK(!g_bluetooth_interface); 4012202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 4022202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray g_bluetooth_interface = test_instance; 4032202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} 4042202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray 4052202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} // namespace hal 4062202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray} // namespace bluetooth 407