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