2 // Copyright (C) 2015 Google, Inc.
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:
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "service/hal/bluetooth_interface.h"
21 #include <base/logging.h>
22 #include <base/observer_list.h>
24 #include "service/logging_helpers.h"
27 #include "btcore/include/hal_util.h"
30 using std::lock_guard;
38 // The global BluetoothInterface instance.
39 BluetoothInterface* g_bluetooth_interface = nullptr;
41 // Mutex used by callbacks to access |g_bluetooth_interface|. Since there is no
42 // good way to unregister callbacks and since the global instance can be deleted
43 // concurrently during shutdown, this lock is used.
45 // TODO(armansito): There should be a way to cleanly shut down the Bluetooth
47 mutex g_instance_lock;
49 // Helper for obtaining the observer list. This is forward declared here and
50 // defined below since it depends on BluetoothInterfaceImpl.
51 base::ObserverList<BluetoothInterface::Observer>* GetObservers();
53 #define FOR_EACH_BLUETOOTH_OBSERVER(func) \
54 FOR_EACH_OBSERVER(BluetoothInterface::Observer, *GetObservers(), func)
56 void AdapterStateChangedCallback(bt_state_t state) {
57 lock_guard<mutex> lock(g_instance_lock);
58 if (!g_bluetooth_interface) {
59 LOG(WARNING) << "Callback received after global instance was destroyed";
63 VLOG(1) << "Adapter state changed: " << BtStateText(state);
64 FOR_EACH_BLUETOOTH_OBSERVER(AdapterStateChangedCallback(state));
67 void AdapterPropertiesCallback(bt_status_t status,
69 bt_property_t* properties) {
70 lock_guard<mutex> lock(g_instance_lock);
71 if (!g_bluetooth_interface) {
72 LOG(WARNING) << "Callback received after global instance was destroyed";
76 VLOG(1) << "Adapter properties changed - status: " << BtStatusText(status)
77 << ", num_properties: " << num_properties;
78 FOR_EACH_BLUETOOTH_OBSERVER(
79 AdapterPropertiesCallback(status, num_properties, properties));
82 void ThreadEventCallback(bt_cb_thread_evt evt) {
83 VLOG(1) << "ThreadEventCallback" << BtEventText(evt);
85 // TODO(armansito): This callback is completely useless to us but btif borks
86 // out if this is not set. Consider making this optional.
89 bool SetWakeAlarmCallout(uint64_t /* delay_millis */,
90 bool /* should_wake */,
93 // TODO(armansito): According to sharvil@, this interface doesn't even need to
94 // exist and can be done entirely from within osi by interfacing directly with
95 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
99 int AcquireWakeLockCallout(const char* /* lock_name */) {
100 // TODO(armansito): According to sharvil@, this interface doesn't even need to
101 // exist and can be done entirely from within osi by interfacing directly with
102 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
103 // Lie here and return success so that enabling and disabling the controller
104 // works before this is properly implemented.
105 return BT_STATUS_SUCCESS;
108 int ReleaseWakeLockCallout(const char* /* lock_name */) {
109 // TODO(armansito): According to sharvil@, this interface doesn't even need to
110 // exist and can be done entirely from within osi by interfacing directly with
111 // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
112 // Lie here and return success so that enabling and disabling the controller
113 // works before this is properly implemented.
114 return BT_STATUS_SUCCESS;
117 // The HAL Bluetooth DM callbacks.
118 bt_callbacks_t bt_callbacks = {
119 sizeof(bt_callbacks_t),
120 AdapterStateChangedCallback,
121 AdapterPropertiesCallback,
122 nullptr, /* remote_device_properties_cb */
123 nullptr, /* device_found_cb */
124 nullptr, /* discovery_state_changed_cb */
125 nullptr, /* pin_request_cb */
126 nullptr, /* ssp_request_cb */
127 nullptr, /* bond_state_changed_cb */
128 nullptr, /* acl_state_changed_cb */
130 nullptr, /* dut_mode_recv_cb */
131 nullptr, /* le_test_mode_cb */
132 nullptr /* energy_info_cb */
135 bt_os_callouts_t bt_os_callouts = {
136 sizeof(bt_os_callouts_t),
138 AcquireWakeLockCallout,
139 ReleaseWakeLockCallout
144 // BluetoothInterface implementation for production.
145 class BluetoothInterfaceImpl : public BluetoothInterface {
147 BluetoothInterfaceImpl()
148 : hal_iface_(nullptr),
149 hal_adapter_(nullptr) {
152 ~BluetoothInterfaceImpl() override {
153 hal_iface_->cleanup();
156 // BluetoothInterface overrides.
157 void AddObserver(Observer* observer) override {
158 lock_guard<mutex> lock(g_instance_lock);
159 observers_.AddObserver(observer);
162 void RemoveObserver(Observer* observer) override {
163 lock_guard<mutex> lock(g_instance_lock);
164 observers_.RemoveObserver(observer);
167 const bt_interface_t* GetHALInterface() const override {
171 const bluetooth_device_t* GetHALAdapter() const override {
175 // Initialize the interface. This loads the shared Bluetooth library and sets
178 // Load the Bluetooth shared library module.
179 const hw_module_t* module;
180 int status = hal_util_load_bt_library(&module);
182 LOG(ERROR) << "Failed to load Bluetooth library";
186 // Open the Bluetooth adapter.
188 status = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
190 LOG(ERROR) << "Failed to open the Bluetooth module";
194 hal_adapter_ = reinterpret_cast<bluetooth_device_t*>(device);
195 hal_iface_ = hal_adapter_->get_bluetooth_interface();
197 // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API
199 status = hal_iface_->init(&bt_callbacks);
200 if (status != BT_STATUS_SUCCESS) {
201 LOG(ERROR) << "Failed to initialize Bluetooth stack";
205 status = hal_iface_->set_os_callouts(&bt_os_callouts);
206 if (status != BT_STATUS_SUCCESS) {
207 LOG(ERROR) << "Failed to set up Bluetooth OS callouts";
214 base::ObserverList<Observer>* observers() { return &observers_; }
217 // List of observers that are interested in notifications from us. We're not
218 // using a base::ObserverListThreadSafe, which it posts observer events
219 // automatically on the origin threads, as we want to avoid that overhead and
220 // simply forward the events to the upper layer.
221 base::ObserverList<Observer> observers_;
223 // The HAL handle obtained from the shared library. We hold a weak reference
224 // to this since the actual data resides in the shared Bluetooth library.
225 const bt_interface_t* hal_iface_;
227 // The HAL handle that represents the underlying Bluetooth adapter. We hold a
228 // weak reference to this since the actual data resides in the shared
229 // Bluetooth library.
230 const bluetooth_device_t* hal_adapter_;
232 DISALLOW_COPY_AND_ASSIGN(BluetoothInterfaceImpl);
237 // Helper for obtaining the observer list from the global instance. This
238 // function is NOT thread safe.
239 base::ObserverList<BluetoothInterface::Observer>* GetObservers() {
240 CHECK(g_bluetooth_interface);
241 return static_cast<BluetoothInterfaceImpl*>(
242 g_bluetooth_interface)->observers();
248 bool BluetoothInterface::Initialize() {
249 lock_guard<mutex> lock(g_instance_lock);
250 CHECK(!g_bluetooth_interface);
252 std::unique_ptr<BluetoothInterfaceImpl> impl(new BluetoothInterfaceImpl());
253 if (!impl->Initialize()) {
254 LOG(ERROR) << "Failed to initialize BluetoothInterface";
258 g_bluetooth_interface = impl.release();
264 void BluetoothInterface::CleanUp() {
265 lock_guard<mutex> lock(g_instance_lock);
266 CHECK(g_bluetooth_interface);
268 delete g_bluetooth_interface;
269 g_bluetooth_interface = nullptr;
273 bool BluetoothInterface::IsInitialized() {
274 lock_guard<mutex> lock(g_instance_lock);
276 return g_bluetooth_interface != nullptr;
280 BluetoothInterface* BluetoothInterface::Get() {
281 lock_guard<mutex> lock(g_instance_lock);
282 CHECK(g_bluetooth_interface);
283 return g_bluetooth_interface;
287 void BluetoothInterface::InitializeForTesting(
288 BluetoothInterface* test_instance) {
289 lock_guard<mutex> lock(g_instance_lock);
290 CHECK(test_instance);
291 CHECK(!g_bluetooth_interface);
293 g_bluetooth_interface = test_instance;
297 } // namespace bluetooth