12202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//
22202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  Copyright (C) 2015 Google, Inc.
32202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//
42202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  Licensed under the Apache License, Version 2.0 (the "License");
52202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  you may not use this file except in compliance with the License.
62202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  You may obtain a copy of the License at:
72202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//
82202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  http://www.apache.org/licenses/LICENSE-2.0
92202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//
102202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  Unless required by applicable law or agreed to in writing, software
112202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  distributed under the License is distributed on an "AS IS" BASIS,
122202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  See the License for the specific language governing permissions and
142202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//  limitations under the License.
152202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray//
162202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
172202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include "service/hal/bluetooth_interface.h"
182202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
192202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include <mutex>
203c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski#include <shared_mutex>
212202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
222202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include <base/logging.h>
232202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include <base/observer_list.h>
242202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
252202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include "service/logging_helpers.h"
262202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
272202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#include "btcore/include/hal_util.h"
282202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
292202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayusing std::lock_guard;
303c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowskiusing std::unique_lock;
313c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowskiusing std::shared_lock;
322202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayusing std::mutex;
331f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He#if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500)
341f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack Heusing shared_mutex_impl = std::shared_mutex;
351f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He#else
361f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack Heusing shared_mutex_impl = std::shared_timed_mutex;
371f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He#endif
382202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
392202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace bluetooth {
402202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace hal {
412202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
422202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace {
432202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
442202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// The global BluetoothInterface instance.
452202cd58a1c623224eae92969f8a0fc8dbd1c17bArman UgurayBluetoothInterface* g_bluetooth_interface = nullptr;
462202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
473c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski// Mutex used by callbacks to access |g_interface|. If we initialize or clean it
483c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski// use unique_lock. If only accessing |g_interface| use shared lock.
49911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson// TODO(jpawlowski): this should be just shared_mutex, as we currently don't use
503c8abb3ef08904ec7605bc81ab20965ea79393a5Jakub Pawlowski// timed methods. Change to shared_mutex when we upgrade to C++14
511f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack Heshared_mutex_impl g_instance_lock;
522202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
532202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// Helper for obtaining the observer list. This is forward declared here and
542202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// defined below since it depends on BluetoothInterfaceImpl.
552202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybase::ObserverList<BluetoothInterface::Observer>* GetObservers();
562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray#define FOR_EACH_BLUETOOTH_OBSERVER(func) \
582202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  FOR_EACH_OBSERVER(BluetoothInterface::Observer, *GetObservers(), func)
592202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define VERIFY_INTERFACE_OR_RETURN()                                   \
61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  do {                                                                 \
62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!g_bluetooth_interface) {                                      \
630f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray      LOG(WARNING) << "Callback received while |g_interface| is NULL"; \
64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;                                                          \
65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }                                                                  \
660f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  } while (0)
670f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
682202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid AdapterStateChangedCallback(bt_state_t state) {
691f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
700f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  VERIFY_INTERFACE_OR_RETURN();
712202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  VLOG(1) << "Adapter state changed: " << BtStateText(state);
722202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  FOR_EACH_BLUETOOTH_OBSERVER(AdapterStateChangedCallback(state));
732202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
742202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid AdapterPropertiesCallback(bt_status_t status, int num_properties,
762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray                               bt_property_t* properties) {
771f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
780f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  VERIFY_INTERFACE_OR_RETURN();
792202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  VLOG(1) << "Adapter properties changed - status: " << BtStatusText(status)
802202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray          << ", num_properties: " << num_properties;
812202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  FOR_EACH_BLUETOOTH_OBSERVER(
822202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      AdapterPropertiesCallback(status, num_properties, properties));
832202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
842202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
85f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowskivoid RemoteDevicePropertiesCallback(bt_status_t status,
869e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                                    RawAddress* remote_bd_addr,
87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                    int num_properties,
88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                    bt_property_t* properties) {
891f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
90f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski  VERIFY_INTERFACE_OR_RETURN();
91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  VLOG(1) << " Remote device properties changed - status: "
92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          << BtStatusText(status)
93f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski          << " - BD_ADDR: " << BtAddrString(remote_bd_addr)
94f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski          << ", num_properties: " << num_properties;
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  FOR_EACH_BLUETOOTH_OBSERVER(RemoteDevicePropertiesCallback(
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      status, remote_bd_addr, num_properties, properties));
97f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski}
98f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski
99fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panickervoid DiscoveryStateChangedCallback(bt_discovery_state_t state) {
1001f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
1010f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  VERIFY_INTERFACE_OR_RETURN();
102fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker  VLOG(1) << "Discovery state changed - state: " << BtDiscoveryStateText(state);
103fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker  FOR_EACH_BLUETOOTH_OBSERVER(DiscoveryStateChangedCallback(state));
104fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker}
105fc616e01fb674e5907e578ae8ecd72b189cfb534Ajay Panicker
1069e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid PinRequestCallback(RawAddress* remote_bd_addr, bt_bdname_t* bd_name,
107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        uint32_t cod, bool min_16_digit) {
1081f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
109c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski  VERIFY_INTERFACE_OR_RETURN();
110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  VLOG(2) << __func__ << " - remote_bd_addr: " << remote_bd_addr
111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          << " - bd_name: " << bd_name << " - cod: " << cod
112c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski          << " - min_16_digit: " << min_16_digit;
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  FOR_EACH_BLUETOOTH_OBSERVER(
114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      PinRequestCallback(remote_bd_addr, bd_name, cod, min_16_digit));
115c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski}
116c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski
1179e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid SSPRequestCallback(RawAddress* remote_bd_addr, bt_bdname_t* bd_name,
118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        uint32_t cod, bt_ssp_variant_t pairing_variant,
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        uint32_t pass_key) {
1201f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
121c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski  VERIFY_INTERFACE_OR_RETURN();
122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  VLOG(2) << __func__ << " - remote_bd_addr: " << remote_bd_addr
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          << " - bd_name: " << bd_name << " - cod: " << cod
124c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski          << " - pairing_variant: " << pairing_variant;
125c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski  FOR_EACH_BLUETOOTH_OBSERVER(SSPRequestCallback(remote_bd_addr, bd_name, cod,
126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                                 pairing_variant, pass_key));
127c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski}
128c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski
1299e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid BondStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                              bt_bond_state_t state) {
1311f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
132c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski  VERIFY_INTERFACE_OR_RETURN();
133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  VLOG(2) << __func__ << " - remote_bd_addr: " << BtAddrString(remote_bd_addr)
134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          << " - status: " << status << " - state: " << state;
135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  FOR_EACH_BLUETOOTH_OBSERVER(
136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BondStateChangedCallback(status, remote_bd_addr, state));
137c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski}
138c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski
1399e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowskivoid AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
1400f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray                             bt_acl_state_t state) {
1411f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
1420f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  VERIFY_INTERFACE_OR_RETURN();
1430f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  CHECK(remote_bd_addr);
1440f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  VLOG(1) << "Remote device ACL state changed - status: "
1450f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray          << BtStatusText(status)
146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          << " - BD_ADDR: " << BtAddrString(remote_bd_addr) << " - state: "
1470f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray          << ((state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED");
1480f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  FOR_EACH_BLUETOOTH_OBSERVER(
1490f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray      AclStateChangedCallback(status, *remote_bd_addr, state));
1500f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray}
1510f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
1522202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid ThreadEventCallback(bt_cb_thread_evt evt) {
1532202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  VLOG(1) << "ThreadEventCallback" << BtEventText(evt);
1542202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
1552202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // TODO(armansito): This callback is completely useless to us but btif borks
1562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // out if this is not set. Consider making this optional.
1572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
1582202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool SetWakeAlarmCallout(uint64_t /* delay_millis */, bool /* should_wake */,
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                         alarm_cb /* cb */, void* /* data */) {
161e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // TODO(armansito): According to sharvil@, this interface doesn't even need to
162e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // exist and can be done entirely from within osi by interfacing directly with
163e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
164e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  return false;
1652202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
1662202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
1672202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayint AcquireWakeLockCallout(const char* /* lock_name */) {
168e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // TODO(armansito): According to sharvil@, this interface doesn't even need to
169e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // exist and can be done entirely from within osi by interfacing directly with
170e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
171d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray  // Lie here and return success so that enabling and disabling the controller
172d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray  // works before this is properly implemented.
173d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray  return BT_STATUS_SUCCESS;
1742202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
1752202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
1762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayint ReleaseWakeLockCallout(const char* /* lock_name */) {
177e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // TODO(armansito): According to sharvil@, this interface doesn't even need to
178e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // exist and can be done entirely from within osi by interfacing directly with
179e2982ad5a15f604218a7cfb37ab1aaed544667d3Arman Uguray  // the kernel. Remove these stubs once that's fixed. (See http://b/23390297)
180d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray  // Lie here and return success so that enabling and disabling the controller
181d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray  // works before this is properly implemented.
182d0835477cb1047b42eef8d740e8d29888b0874c6Arman Uguray  return BT_STATUS_SUCCESS;
1832202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
1842202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
1852202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// The HAL Bluetooth DM callbacks.
1862202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybt_callbacks_t bt_callbacks = {
187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    sizeof(bt_callbacks_t),
188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    AdapterStateChangedCallback,
189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    AdapterPropertiesCallback,
190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    RemoteDevicePropertiesCallback,
191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    nullptr, /* device_found_cb */
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    DiscoveryStateChangedCallback,
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    PinRequestCallback,
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SSPRequestCallback,
195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BondStateChangedCallback,
196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    AclStateChangedCallback,
197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ThreadEventCallback,
198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    nullptr, /* dut_mode_recv_cb */
199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    nullptr, /* le_test_mode_cb */
200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    nullptr  /* energy_info_cb */
2012202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray};
2022202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbt_os_callouts_t bt_os_callouts = {sizeof(bt_os_callouts_t),
204911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   SetWakeAlarmCallout, AcquireWakeLockCallout,
205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   ReleaseWakeLockCallout};
2062202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2072202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}  // namespace
2082202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2092202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// BluetoothInterface implementation for production.
2102202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayclass BluetoothInterfaceImpl : public BluetoothInterface {
2112202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray public:
212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BluetoothInterfaceImpl() : hal_iface_(nullptr), hal_adapter_(nullptr) {}
2132202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2142202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  ~BluetoothInterfaceImpl() override {
215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (hal_iface_) hal_iface_->cleanup();
21642c89a0e5f3e2771681ebd11281d6e3c20341894Ajay Panicker  }
2172202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2182202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // BluetoothInterface overrides.
2192202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  void AddObserver(Observer* observer) override {
2201f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He    shared_lock<shared_mutex_impl> lock(g_instance_lock);
2212202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    observers_.AddObserver(observer);
2222202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  }
2232202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2242202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  void RemoveObserver(Observer* observer) override {
2251f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He    shared_lock<shared_mutex_impl> lock(g_instance_lock);
2262202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    observers_.RemoveObserver(observer);
2272202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  }
2282202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  const bt_interface_t* GetHALInterface() const override { return hal_iface_; }
2302202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
231a3292051d9c088769b0f4e46ffaf7c66b1127194Pavlin Radoslavov  bt_callbacks_t* GetHALCallbacks() const override { return &bt_callbacks; }
232a3292051d9c088769b0f4e46ffaf7c66b1127194Pavlin Radoslavov
2332202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  const bluetooth_device_t* GetHALAdapter() const override {
2342202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    return hal_adapter_;
2352202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  }
2362202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2372202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // Initialize the interface. This loads the shared Bluetooth library and sets
2382202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // up the callbacks.
2392202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  bool Initialize() {
2402202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    // Load the Bluetooth shared library module.
2412202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    const hw_module_t* module;
2422202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    int status = hal_util_load_bt_library(&module);
2432202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    if (status) {
24442c89a0e5f3e2771681ebd11281d6e3c20341894Ajay Panicker      LOG(ERROR) << "Failed to load Bluetooth library: " << status;
2452202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      return false;
2462202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    }
2472202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2482202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    // Open the Bluetooth adapter.
2492202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    hw_device_t* device;
2502202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    status = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
2512202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    if (status) {
2522202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      LOG(ERROR) << "Failed to open the Bluetooth module";
2532202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      return false;
2542202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    }
2552202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    hal_adapter_ = reinterpret_cast<bluetooth_device_t*>(device);
2572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    hal_iface_ = hal_adapter_->get_bluetooth_interface();
2582202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2592202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API
2602202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    // callbacks.
2612202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    status = hal_iface_->init(&bt_callbacks);
2622202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    if (status != BT_STATUS_SUCCESS) {
2632202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      LOG(ERROR) << "Failed to initialize Bluetooth stack";
2642202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      return false;
2652202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    }
2662202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2672202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    status = hal_iface_->set_os_callouts(&bt_os_callouts);
2682202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    if (status != BT_STATUS_SUCCESS) {
2692202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      LOG(ERROR) << "Failed to set up Bluetooth OS callouts";
2702202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray      return false;
2712202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    }
2722202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2732202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    return true;
2742202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  }
2752202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  base::ObserverList<Observer>* observers() { return &observers_; }
2772202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2782202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray private:
2792202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // List of observers that are interested in notifications from us. We're not
2802202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // using a base::ObserverListThreadSafe, which it posts observer events
2812202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // automatically on the origin threads, as we want to avoid that overhead and
2822202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // simply forward the events to the upper layer.
2832202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  base::ObserverList<Observer> observers_;
2842202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2852202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // The HAL handle obtained from the shared library. We hold a weak reference
2862202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // to this since the actual data resides in the shared Bluetooth library.
2872202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  const bt_interface_t* hal_iface_;
2882202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2892202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // The HAL handle that represents the underlying Bluetooth adapter. We hold a
2902202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // weak reference to this since the actual data resides in the shared
2912202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  // Bluetooth library.
2922202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  const bluetooth_device_t* hal_adapter_;
2932202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2942202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  DISALLOW_COPY_AND_ASSIGN(BluetoothInterfaceImpl);
2952202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray};
2962202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2972202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraynamespace {
2982202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
2992202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// Helper for obtaining the observer list from the global instance. This
3002202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// function is NOT thread safe.
3012202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybase::ObserverList<BluetoothInterface::Observer>* GetObservers() {
3022202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  CHECK(g_bluetooth_interface);
303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return static_cast<BluetoothInterfaceImpl*>(g_bluetooth_interface)
304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ->observers();
3052202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
3062202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3072202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}  // namespace
3082202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
309c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker// Default observer implementations. These are provided so that the methods
310c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker// themselves are optional.
311c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panickervoid BluetoothInterface::Observer::AdapterStateChangedCallback(
312c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker    bt_state_t /* state*/) {
313c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker  // Do nothing.
314c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker}
315c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker
316c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panickervoid BluetoothInterface::Observer::AdapterPropertiesCallback(
317911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bt_status_t /* status */, int /* num_properties */,
318c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker    bt_property_t* /* properties */) {
319c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker  // Do nothing.
320c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker}
321c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker
322f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowskivoid BluetoothInterface::Observer::RemoteDevicePropertiesCallback(
3239e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski    bt_status_t /* status */, RawAddress* /* remote_bd_addr */,
324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    int /* num_properties */, bt_property_t* /* properties */) {
325f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski  // Do nothing.
326f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski}
327f40f0d09c38cfecd9fae5879a3aeabfa86538525Jakub Pawlowski
328c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panickervoid BluetoothInterface::Observer::DiscoveryStateChangedCallback(
329c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker    bt_discovery_state_t /* state */) {
330c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker  // Do nothing.
331c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker}
332c2a61ac0a96ba21ff99c396e14a0e6b42ccf9e79Ajay Panicker
333c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowskivoid BluetoothInterface::Observer::PinRequestCallback(
3349e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski    RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
335c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski    bool min_16_digit) {
336c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski  // Do nothing.
337c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski}
338c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski
339c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowskivoid BluetoothInterface::Observer::SSPRequestCallback(
3409e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski    RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
342c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski  // Do nothing.
343c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski}
344c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski
345c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowskivoid BluetoothInterface::Observer::BondStateChangedCallback(
3469e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski    bt_status_t status, RawAddress* remote_bd_addr, bt_bond_state_t state) {
347c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski  // Do nothing.
348c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski}
349c2ffe4e1f1a87da6a9613481e8beaeb516b8da59Jakub Pawlowski
3500f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Ugurayvoid BluetoothInterface::Observer::AclStateChangedCallback(
3519e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski    bt_status_t /* status */, const RawAddress& /* remote_bdaddr */,
3520f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray    bt_acl_state_t /* state */) {
3530f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  // Do nothing.
3540f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray}
3550f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
3562202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static
3572202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguraybool BluetoothInterface::Initialize() {
3581f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  unique_lock<shared_mutex_impl> lock(g_instance_lock);
3592202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  CHECK(!g_bluetooth_interface);
3602202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3612202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  std::unique_ptr<BluetoothInterfaceImpl> impl(new BluetoothInterfaceImpl());
3622202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  if (!impl->Initialize()) {
3632202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    LOG(ERROR) << "Failed to initialize BluetoothInterface";
3642202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    return false;
3652202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  }
3662202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3672202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  g_bluetooth_interface = impl.release();
3682202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3692202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  return true;
3702202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
3712202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3722202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static
3732202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid BluetoothInterface::CleanUp() {
3741f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  unique_lock<shared_mutex_impl> lock(g_instance_lock);
3752202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  CHECK(g_bluetooth_interface);
3762202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3772202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  delete g_bluetooth_interface;
3782202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  g_bluetooth_interface = nullptr;
3792202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
3802202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3812202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static
3829ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguraybool BluetoothInterface::IsInitialized() {
3831f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
3849ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray
3859ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray  return g_bluetooth_interface != nullptr;
3869ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray}
3879ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray
3889ded7b6175825afdac0e2cebef8755e4d7b03103Arman Uguray// static
3892202cd58a1c623224eae92969f8a0fc8dbd1c17bArman UgurayBluetoothInterface* BluetoothInterface::Get() {
3901f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  shared_lock<shared_mutex_impl> lock(g_instance_lock);
3912202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  CHECK(g_bluetooth_interface);
3922202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  return g_bluetooth_interface;
3932202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
3942202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
3952202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray// static
3962202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Ugurayvoid BluetoothInterface::InitializeForTesting(
3972202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray    BluetoothInterface* test_instance) {
3981f60d2def863f5c58c731f2db6f29f9c1ee5af6fJack He  unique_lock<shared_mutex_impl> lock(g_instance_lock);
3992202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  CHECK(test_instance);
4002202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  CHECK(!g_bluetooth_interface);
4012202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
4022202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray  g_bluetooth_interface = test_instance;
4032202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}
4042202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray
4052202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}  // namespace hal
4062202cd58a1c623224eae92969f8a0fc8dbd1c17bArman Uguray}  // namespace bluetooth
407