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 
29 extern "C" {
30 #include "btcore/include/hal_util.h"
31 }  // extern "C"
32 
33 using std::lock_guard;
34 using std::unique_lock;
35 using std::shared_lock;
36 using std::mutex;
37 using std::shared_timed_mutex;
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_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.
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_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 
AdapterPropertiesCallback(bt_status_t status,int num_properties,bt_property_t * properties)75 void 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 
RemoteDevicePropertiesCallback(bt_status_t status,bt_bdaddr_t * remote_bd_addr,int num_properties,bt_property_t * properties)86 void 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 
DiscoveryStateChangedCallback(bt_discovery_state_t state)100 void 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 
PinRequestCallback(bt_bdaddr_t * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bool min_16_digit)107 void 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 
SSPRequestCallback(bt_bdaddr_t * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bt_ssp_variant_t pairing_variant,uint32_t pass_key)119 void 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 
BondStateChangedCallback(bt_status_t status,bt_bdaddr_t * remote_bd_addr,bt_bond_state_t state)132 void 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 
AclStateChangedCallback(bt_status_t status,bt_bdaddr_t * remote_bd_addr,bt_acl_state_t state)145 void 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 
ThreadEventCallback(bt_cb_thread_evt evt)160 void 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 
SetWakeAlarmCallout(uint64_t,bool,alarm_cb,void *)167 bool 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 
AcquireWakeLockCallout(const char *)177 int 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 
ReleaseWakeLockCallout(const char *)186 int 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.
196 bt_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 
213 bt_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.
223 class BluetoothInterfaceImpl : public BluetoothInterface {
224  public:
BluetoothInterfaceImpl()225   BluetoothInterfaceImpl()
226       : hal_iface_(nullptr),
227         hal_adapter_(nullptr) {
228   }
229 
~BluetoothInterfaceImpl()230   ~BluetoothInterfaceImpl() override {
231     if (hal_iface_)
232         hal_iface_->cleanup();
233   }
234 
235   // BluetoothInterface overrides.
AddObserver(Observer * observer)236   void AddObserver(Observer* observer) override {
237     shared_lock<shared_timed_mutex> lock(g_instance_lock);
238     observers_.AddObserver(observer);
239   }
240 
RemoveObserver(Observer * observer)241   void RemoveObserver(Observer* observer) override {
242     shared_lock<shared_timed_mutex> lock(g_instance_lock);
243     observers_.RemoveObserver(observer);
244   }
245 
GetHALInterface() const246   const bt_interface_t* GetHALInterface() const override {
247     return hal_iface_;
248   }
249 
GetHALAdapter() const250   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.
Initialize()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 
observers()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 
314 namespace {
315 
316 // Helper for obtaining the observer list from the global instance. This
317 // function is NOT thread safe.
GetObservers()318 base::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.
AdapterStateChangedCallback(bt_state_t)328 void BluetoothInterface::Observer::AdapterStateChangedCallback(
329     bt_state_t /* state*/) {
330   // Do nothing.
331 }
332 
AdapterPropertiesCallback(bt_status_t,int,bt_property_t *)333 void BluetoothInterface::Observer::AdapterPropertiesCallback(
334     bt_status_t /* status */,
335     int /* num_properties */,
336     bt_property_t* /* properties */) {
337   // Do nothing.
338 }
339 
RemoteDevicePropertiesCallback(bt_status_t,bt_bdaddr_t *,int,bt_property_t *)340 void 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 
DiscoveryStateChangedCallback(bt_discovery_state_t)348 void BluetoothInterface::Observer::DiscoveryStateChangedCallback(
349     bt_discovery_state_t /* state */) {
350   // Do nothing.
351 }
352 
PinRequestCallback(bt_bdaddr_t * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bool min_16_digit)353 void 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 
SSPRequestCallback(bt_bdaddr_t * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bt_ssp_variant_t pairing_variant,uint32_t pass_key)361 void 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 
BondStateChangedCallback(bt_status_t status,bt_bdaddr_t * remote_bd_addr,bt_bond_state_t state)370 void 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 
AclStateChangedCallback(bt_status_t,const bt_bdaddr_t &,bt_acl_state_t)377 void 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
Initialize()385 bool 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
CleanUp()401 void 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
IsInitialized()410 bool BluetoothInterface::IsInitialized() {
411   shared_lock<shared_timed_mutex> lock(g_instance_lock);
412 
413   return g_bluetooth_interface != nullptr;
414 }
415 
416 // static
Get()417 BluetoothInterface* 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
InitializeForTesting(BluetoothInterface * test_instance)424 void 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