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