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