• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AdapterStateChangedCallback(bt_state_t state)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 
AdapterPropertiesCallback(bt_status_t status,int num_properties,bt_property_t * properties)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 
RemoteDevicePropertiesCallback(bt_status_t status,RawAddress * remote_bd_addr,int num_properties,bt_property_t * properties)85 void RemoteDevicePropertiesCallback(bt_status_t status,
86                                     RawAddress* 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 
DiscoveryStateChangedCallback(bt_discovery_state_t state)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 
PinRequestCallback(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bool min_16_digit)106 void PinRequestCallback(RawAddress* 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 
SSPRequestCallback(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bt_ssp_variant_t pairing_variant,uint32_t pass_key)117 void SSPRequestCallback(RawAddress* 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 
BondStateChangedCallback(bt_status_t status,RawAddress * remote_bd_addr,bt_bond_state_t state)129 void BondStateChangedCallback(bt_status_t status, RawAddress* 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 
AclStateChangedCallback(bt_status_t status,RawAddress * remote_bd_addr,bt_acl_state_t state)139 void AclStateChangedCallback(bt_status_t status, RawAddress* 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 
ThreadEventCallback(bt_cb_thread_evt evt)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 
SetWakeAlarmCallout(uint64_t,bool,alarm_cb,void *)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 
AcquireWakeLockCallout(const char *)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 
ReleaseWakeLockCallout(const char *)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:
BluetoothInterfaceImpl()212   BluetoothInterfaceImpl() : hal_iface_(nullptr), hal_adapter_(nullptr) {}
213 
~BluetoothInterfaceImpl()214   ~BluetoothInterfaceImpl() override {
215     if (hal_iface_) hal_iface_->cleanup();
216   }
217 
218   // BluetoothInterface overrides.
AddObserver(Observer * observer)219   void AddObserver(Observer* observer) override {
220     shared_lock<shared_mutex_impl> lock(g_instance_lock);
221     observers_.AddObserver(observer);
222   }
223 
RemoveObserver(Observer * observer)224   void RemoveObserver(Observer* observer) override {
225     shared_lock<shared_mutex_impl> lock(g_instance_lock);
226     observers_.RemoveObserver(observer);
227   }
228 
GetHALInterface() const229   const bt_interface_t* GetHALInterface() const override { return hal_iface_; }
230 
GetHALCallbacks() const231   bt_callbacks_t* GetHALCallbacks() const override { return &bt_callbacks; }
232 
GetHALAdapter() const233   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.
Initialize()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 
observers()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.
GetObservers()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.
AdapterStateChangedCallback(bt_state_t)311 void BluetoothInterface::Observer::AdapterStateChangedCallback(
312     bt_state_t /* state*/) {
313   // Do nothing.
314 }
315 
AdapterPropertiesCallback(bt_status_t,int,bt_property_t *)316 void BluetoothInterface::Observer::AdapterPropertiesCallback(
317     bt_status_t /* status */, int /* num_properties */,
318     bt_property_t* /* properties */) {
319   // Do nothing.
320 }
321 
RemoteDevicePropertiesCallback(bt_status_t,RawAddress *,int,bt_property_t *)322 void BluetoothInterface::Observer::RemoteDevicePropertiesCallback(
323     bt_status_t /* status */, RawAddress* /* remote_bd_addr */,
324     int /* num_properties */, bt_property_t* /* properties */) {
325   // Do nothing.
326 }
327 
DiscoveryStateChangedCallback(bt_discovery_state_t)328 void BluetoothInterface::Observer::DiscoveryStateChangedCallback(
329     bt_discovery_state_t /* state */) {
330   // Do nothing.
331 }
332 
PinRequestCallback(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bool min_16_digit)333 void BluetoothInterface::Observer::PinRequestCallback(
334     RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
335     bool min_16_digit) {
336   // Do nothing.
337 }
338 
SSPRequestCallback(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bt_ssp_variant_t pairing_variant,uint32_t pass_key)339 void BluetoothInterface::Observer::SSPRequestCallback(
340     RawAddress* 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 
BondStateChangedCallback(bt_status_t status,RawAddress * remote_bd_addr,bt_bond_state_t state)345 void BluetoothInterface::Observer::BondStateChangedCallback(
346     bt_status_t status, RawAddress* remote_bd_addr, bt_bond_state_t state) {
347   // Do nothing.
348 }
349 
AclStateChangedCallback(bt_status_t,const RawAddress &,bt_acl_state_t)350 void BluetoothInterface::Observer::AclStateChangedCallback(
351     bt_status_t /* status */, const RawAddress& /* remote_bdaddr */,
352     bt_acl_state_t /* state */) {
353   // Do nothing.
354 }
355 
356 // static
Initialize()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
CleanUp()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
IsInitialized()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
Get()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
InitializeForTesting(BluetoothInterface * test_instance)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