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