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