Loading bluetooth/1.0/default/bluetooth_hci.cc +25 −2 Original line number Diff line number Diff line Loading @@ -33,7 +33,8 @@ static const uint8_t HCI_DATA_TYPE_SCO = 3; class BluetoothDeathRecipient : public hidl_death_recipient { public: BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {} BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci), has_died_(false) {} virtual void serviceDied( uint64_t /*cookie*/, Loading @@ -51,7 +52,7 @@ class BluetoothDeathRecipient : public hidl_death_recipient { }; BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {} : death_recipient_(new BluetoothDeathRecipient(this)) {bt_enabled = 0;} Return<void> BluetoothHci::initialize( const ::android::sp<IBluetoothHciCallbacks>& cb) { Loading @@ -61,8 +62,19 @@ Return<void> BluetoothHci::initialize( return Void(); } if (bt_enabled == 1) { ALOGE("initialize was called!"); return Void(); } bt_enabled = 1; death_recipient_->setHasDied(false); cb->linkToDeath(death_recipient_, 0); unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) ALOGI("Skipping unlink call, service died."); else cb->unlinkToDeath(death_recipient); }; bool rc = VendorInterface::Initialize( [cb](bool status) { Loading Loading @@ -112,6 +124,12 @@ Return<void> BluetoothHci::initialize( Return<void> BluetoothHci::close() { ALOGI("BluetoothHci::close()"); if (bt_enabled != 1) { ALOGE("should initialize first!"); return Void(); } bt_enabled = 0; unlink_cb_(death_recipient_); VendorInterface::Shutdown(); return Void(); Loading @@ -134,6 +152,11 @@ Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) { void BluetoothHci::sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data) { if (bt_enabled != 1) { ALOGE("should initialize first!"); return; } VendorInterface::get()->Send(type, data.data(), data.size()); } Loading bluetooth/1.0/default/bluetooth_hci.h +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ class BluetoothHci : public IBluetoothHci { void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data); ::android::sp<BluetoothDeathRecipient> death_recipient_; std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_; int bt_enabled; }; extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name); Loading bluetooth/1.0/default/vendor_interface.cc +179 −113 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ static const char* VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE"; static const int INVALID_FD = -1; std::mutex vendor_mutex_; std::mutex initcb_mutex_; namespace { Loading @@ -47,13 +49,25 @@ struct { uint16_t opcode; } internal_command; enum { VENDOR_STATE_INIT = 1, VENDOR_STATE_OPENING, /* during opening */ VENDOR_STATE_OPENED, /* open in fops_open */ VENDOR_STATE_CLOSING, /* during closing */ VENDOR_STATE_CLOSED, /* closed */ VENDOR_STATE_MSG_NUM } ; uint8_t vstate = VENDOR_STATE_INIT; // True when LPM is not enabled yet or wake is not asserted. bool lpm_wake_deasserted; uint32_t lpm_timeout_ms; bool recent_activity_flag; VendorInterface* g_vendor_interface = nullptr; std::mutex wakeup_mutex_; static VendorInterface vendor_interface; HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) { size_t packet_size = data.size() + sizeof(HC_BT_HDR); Loading Loading @@ -167,11 +181,8 @@ bool VendorInterface::Initialize( InitializeCompleteCallback initialize_complete_cb, PacketReadCallback event_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb, PacketReadCallback iso_cb) { if (g_vendor_interface) { ALOGE("%s: No previous Shutdown()?", __func__); return false; } g_vendor_interface = new VendorInterface(); ALOGI("%s: VendorInterface::Initialize", __func__); g_vendor_interface = &vendor_interface; return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb, sco_cb, iso_cb); } Loading @@ -179,9 +190,8 @@ bool VendorInterface::Initialize( void VendorInterface::Shutdown() { LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!", __func__); ALOGI("%s: VendorInterface::Shutdown", __func__); g_vendor_interface->Close(); delete g_vendor_interface; g_vendor_interface = nullptr; } VendorInterface* VendorInterface::get() { return g_vendor_interface; } Loading @@ -191,8 +201,23 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb, PacketReadCallback iso_cb) { initialize_complete_cb_ = initialize_complete_cb; { std::unique_lock<std::mutex> guard(vendor_mutex_); if (vstate == VENDOR_STATE_OPENED) { ALOGW("VendorInterface opened!"); return true; } if ((vstate == VENDOR_STATE_CLOSING) || (vstate == VENDOR_STATE_OPENING)) { ALOGW("VendorInterface open/close is on-going !"); return true; } vstate = VENDOR_STATE_OPENING; ALOGI("%s: VendorInterface::Open", __func__); initialize_complete_cb_ = initialize_complete_cb; // Initialize vendor interface lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW); Loading @@ -212,9 +237,10 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, // Get the local BD address uint8_t local_bda[BluetoothAddress::kBytes]; uint8_t local_bda[BluetoothAddress::kBytes] = {0, 0, 0, 0, 0, 0}; if (!BluetoothAddress::get_local_address(local_bda)) { LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__); // BT driver will get BD address from NVRAM for MTK solution ALOGW("%s: No pre-set Bluetooth Address!", __func__); } int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda); if (status) { Loading Loading @@ -263,7 +289,8 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, fd_watcher_.WatchFdForNonBlockingReads( fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); }); fd_watcher_.WatchFdForNonBlockingReads( fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); }); fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); }); hci_ = mct_hci; } Loading @@ -274,19 +301,33 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, firmware_startup_timer_ = new FirmwareStartupTimer(); lib_interface_->op(BT_VND_OP_FW_CFG, nullptr); vstate = VENDOR_STATE_OPENED; ALOGI("%s: VendorInterface::Open done!!!", __func__); } // vendor_mutex_ done return true; } void VendorInterface::Close() { // These callbacks may send HCI events (vendor-dependent), so make sure to // StopWatching the file descriptor after this. if (vstate != VENDOR_STATE_OPENED) { ALOGW("VendorInterface is not allow close(%d)", vstate); return; } vstate = VENDOR_STATE_CLOSING; ALOGI("%s: VendorInterface::Close", __func__); if (lib_interface_ != nullptr) { lib_interface_->cleanup(); bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE; lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode); } fd_watcher_.StopWatchingFileDescriptors(); { std::unique_lock<std::mutex> guard(vendor_mutex_); fd_watcher_.StopWatchingFileDescriptors(); if (hci_ != nullptr) { delete hci_; hci_ = nullptr; Loading @@ -298,7 +339,6 @@ void VendorInterface::Close() { int power_state = BT_VND_PWR_OFF; lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state); lib_interface_->cleanup(); lib_interface_ = nullptr; } Loading @@ -311,12 +351,26 @@ void VendorInterface::Close() { delete firmware_startup_timer_; firmware_startup_timer_ = nullptr; } vstate = VENDOR_STATE_CLOSED; } // vendor_mutex_ done ALOGI("%s: VendorInterface::Close done!!!", __func__); } size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) { std::unique_lock<std::mutex> lock(wakeup_mutex_); recent_activity_flag = true; { std::unique_lock<std::mutex> guard(vendor_mutex_); if (vstate != VENDOR_STATE_OPENED) { ALOGW("VendorInterface is not open yet(%d)!", vstate); return 0; } ALOGI("%s: VendorInterface::Send", __func__); if (lib_interface_ == nullptr) { ALOGE("lib_interface_ is null"); return 0; } recent_activity_flag = true; if (lpm_wake_deasserted == true) { // Restart the timer. fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms), Loading @@ -328,7 +382,8 @@ size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) { ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8)); } return hci_->Send(type, data, length); return hci_ ? hci_->Send(type, data, length) : 0; } // vendor_mutex_ done } void VendorInterface::OnFirmwareConfigured(uint8_t result) { Loading @@ -339,11 +394,17 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) { firmware_startup_timer_ = nullptr; } { std::unique_lock<std::mutex> guard(initcb_mutex_); ALOGD("%s OnFirmwareConfigured get lock", __func__); if (initialize_complete_cb_ != nullptr) { LOG_ALWAYS_FATAL_IF((result != 0), "%s: Failed to init firmware!", __func__); initialize_complete_cb_(result == 0); initialize_complete_cb_ = nullptr; } } // initcb_mutex_ done if (lib_interface_ != nullptr) { lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms); ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms); Loading @@ -354,10 +415,15 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) { fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms), [this]() { OnTimeout(); }); } else { ALOGE("lib_interface_ is null"); } initialize_complete_cb_ = nullptr; } void VendorInterface::OnTimeout() { ALOGV("%s", __func__); std::unique_lock<std::mutex> lock(wakeup_mutex_); if (recent_activity_flag == false) { lpm_wake_deasserted = true; bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT; Loading bluetooth/1.0/default/vendor_interface.h +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #include "bt_vendor_lib.h" #include "hci_protocol.h" extern std::mutex initcb_mutex_; namespace android { namespace hardware { namespace bluetooth { Loading @@ -45,10 +47,9 @@ class VendorInterface { size_t Send(uint8_t type, const uint8_t* data, size_t length); void OnFirmwareConfigured(uint8_t result); private: virtual ~VendorInterface() = default; private: bool Open(InitializeCompleteCallback initialize_complete_cb, PacketReadCallback event_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb, PacketReadCallback iso_cb); Loading Loading
bluetooth/1.0/default/bluetooth_hci.cc +25 −2 Original line number Diff line number Diff line Loading @@ -33,7 +33,8 @@ static const uint8_t HCI_DATA_TYPE_SCO = 3; class BluetoothDeathRecipient : public hidl_death_recipient { public: BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {} BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci), has_died_(false) {} virtual void serviceDied( uint64_t /*cookie*/, Loading @@ -51,7 +52,7 @@ class BluetoothDeathRecipient : public hidl_death_recipient { }; BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {} : death_recipient_(new BluetoothDeathRecipient(this)) {bt_enabled = 0;} Return<void> BluetoothHci::initialize( const ::android::sp<IBluetoothHciCallbacks>& cb) { Loading @@ -61,8 +62,19 @@ Return<void> BluetoothHci::initialize( return Void(); } if (bt_enabled == 1) { ALOGE("initialize was called!"); return Void(); } bt_enabled = 1; death_recipient_->setHasDied(false); cb->linkToDeath(death_recipient_, 0); unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) ALOGI("Skipping unlink call, service died."); else cb->unlinkToDeath(death_recipient); }; bool rc = VendorInterface::Initialize( [cb](bool status) { Loading Loading @@ -112,6 +124,12 @@ Return<void> BluetoothHci::initialize( Return<void> BluetoothHci::close() { ALOGI("BluetoothHci::close()"); if (bt_enabled != 1) { ALOGE("should initialize first!"); return Void(); } bt_enabled = 0; unlink_cb_(death_recipient_); VendorInterface::Shutdown(); return Void(); Loading @@ -134,6 +152,11 @@ Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) { void BluetoothHci::sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data) { if (bt_enabled != 1) { ALOGE("should initialize first!"); return; } VendorInterface::get()->Send(type, data.data(), data.size()); } Loading
bluetooth/1.0/default/bluetooth_hci.h +1 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ class BluetoothHci : public IBluetoothHci { void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data); ::android::sp<BluetoothDeathRecipient> death_recipient_; std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_; int bt_enabled; }; extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name); Loading
bluetooth/1.0/default/vendor_interface.cc +179 −113 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ static const char* VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE"; static const int INVALID_FD = -1; std::mutex vendor_mutex_; std::mutex initcb_mutex_; namespace { Loading @@ -47,13 +49,25 @@ struct { uint16_t opcode; } internal_command; enum { VENDOR_STATE_INIT = 1, VENDOR_STATE_OPENING, /* during opening */ VENDOR_STATE_OPENED, /* open in fops_open */ VENDOR_STATE_CLOSING, /* during closing */ VENDOR_STATE_CLOSED, /* closed */ VENDOR_STATE_MSG_NUM } ; uint8_t vstate = VENDOR_STATE_INIT; // True when LPM is not enabled yet or wake is not asserted. bool lpm_wake_deasserted; uint32_t lpm_timeout_ms; bool recent_activity_flag; VendorInterface* g_vendor_interface = nullptr; std::mutex wakeup_mutex_; static VendorInterface vendor_interface; HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) { size_t packet_size = data.size() + sizeof(HC_BT_HDR); Loading Loading @@ -167,11 +181,8 @@ bool VendorInterface::Initialize( InitializeCompleteCallback initialize_complete_cb, PacketReadCallback event_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb, PacketReadCallback iso_cb) { if (g_vendor_interface) { ALOGE("%s: No previous Shutdown()?", __func__); return false; } g_vendor_interface = new VendorInterface(); ALOGI("%s: VendorInterface::Initialize", __func__); g_vendor_interface = &vendor_interface; return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb, sco_cb, iso_cb); } Loading @@ -179,9 +190,8 @@ bool VendorInterface::Initialize( void VendorInterface::Shutdown() { LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!", __func__); ALOGI("%s: VendorInterface::Shutdown", __func__); g_vendor_interface->Close(); delete g_vendor_interface; g_vendor_interface = nullptr; } VendorInterface* VendorInterface::get() { return g_vendor_interface; } Loading @@ -191,8 +201,23 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb, PacketReadCallback iso_cb) { initialize_complete_cb_ = initialize_complete_cb; { std::unique_lock<std::mutex> guard(vendor_mutex_); if (vstate == VENDOR_STATE_OPENED) { ALOGW("VendorInterface opened!"); return true; } if ((vstate == VENDOR_STATE_CLOSING) || (vstate == VENDOR_STATE_OPENING)) { ALOGW("VendorInterface open/close is on-going !"); return true; } vstate = VENDOR_STATE_OPENING; ALOGI("%s: VendorInterface::Open", __func__); initialize_complete_cb_ = initialize_complete_cb; // Initialize vendor interface lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW); Loading @@ -212,9 +237,10 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, // Get the local BD address uint8_t local_bda[BluetoothAddress::kBytes]; uint8_t local_bda[BluetoothAddress::kBytes] = {0, 0, 0, 0, 0, 0}; if (!BluetoothAddress::get_local_address(local_bda)) { LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__); // BT driver will get BD address from NVRAM for MTK solution ALOGW("%s: No pre-set Bluetooth Address!", __func__); } int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda); if (status) { Loading Loading @@ -263,7 +289,8 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, fd_watcher_.WatchFdForNonBlockingReads( fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); }); fd_watcher_.WatchFdForNonBlockingReads( fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); }); fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); }); hci_ = mct_hci; } Loading @@ -274,19 +301,33 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb, firmware_startup_timer_ = new FirmwareStartupTimer(); lib_interface_->op(BT_VND_OP_FW_CFG, nullptr); vstate = VENDOR_STATE_OPENED; ALOGI("%s: VendorInterface::Open done!!!", __func__); } // vendor_mutex_ done return true; } void VendorInterface::Close() { // These callbacks may send HCI events (vendor-dependent), so make sure to // StopWatching the file descriptor after this. if (vstate != VENDOR_STATE_OPENED) { ALOGW("VendorInterface is not allow close(%d)", vstate); return; } vstate = VENDOR_STATE_CLOSING; ALOGI("%s: VendorInterface::Close", __func__); if (lib_interface_ != nullptr) { lib_interface_->cleanup(); bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE; lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode); } fd_watcher_.StopWatchingFileDescriptors(); { std::unique_lock<std::mutex> guard(vendor_mutex_); fd_watcher_.StopWatchingFileDescriptors(); if (hci_ != nullptr) { delete hci_; hci_ = nullptr; Loading @@ -298,7 +339,6 @@ void VendorInterface::Close() { int power_state = BT_VND_PWR_OFF; lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state); lib_interface_->cleanup(); lib_interface_ = nullptr; } Loading @@ -311,12 +351,26 @@ void VendorInterface::Close() { delete firmware_startup_timer_; firmware_startup_timer_ = nullptr; } vstate = VENDOR_STATE_CLOSED; } // vendor_mutex_ done ALOGI("%s: VendorInterface::Close done!!!", __func__); } size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) { std::unique_lock<std::mutex> lock(wakeup_mutex_); recent_activity_flag = true; { std::unique_lock<std::mutex> guard(vendor_mutex_); if (vstate != VENDOR_STATE_OPENED) { ALOGW("VendorInterface is not open yet(%d)!", vstate); return 0; } ALOGI("%s: VendorInterface::Send", __func__); if (lib_interface_ == nullptr) { ALOGE("lib_interface_ is null"); return 0; } recent_activity_flag = true; if (lpm_wake_deasserted == true) { // Restart the timer. fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms), Loading @@ -328,7 +382,8 @@ size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) { ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8)); } return hci_->Send(type, data, length); return hci_ ? hci_->Send(type, data, length) : 0; } // vendor_mutex_ done } void VendorInterface::OnFirmwareConfigured(uint8_t result) { Loading @@ -339,11 +394,17 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) { firmware_startup_timer_ = nullptr; } { std::unique_lock<std::mutex> guard(initcb_mutex_); ALOGD("%s OnFirmwareConfigured get lock", __func__); if (initialize_complete_cb_ != nullptr) { LOG_ALWAYS_FATAL_IF((result != 0), "%s: Failed to init firmware!", __func__); initialize_complete_cb_(result == 0); initialize_complete_cb_ = nullptr; } } // initcb_mutex_ done if (lib_interface_ != nullptr) { lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms); ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms); Loading @@ -354,10 +415,15 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) { fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms), [this]() { OnTimeout(); }); } else { ALOGE("lib_interface_ is null"); } initialize_complete_cb_ = nullptr; } void VendorInterface::OnTimeout() { ALOGV("%s", __func__); std::unique_lock<std::mutex> lock(wakeup_mutex_); if (recent_activity_flag == false) { lpm_wake_deasserted = true; bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT; Loading
bluetooth/1.0/default/vendor_interface.h +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #include "bt_vendor_lib.h" #include "hci_protocol.h" extern std::mutex initcb_mutex_; namespace android { namespace hardware { namespace bluetooth { Loading @@ -45,10 +47,9 @@ class VendorInterface { size_t Send(uint8_t type, const uint8_t* data, size_t length); void OnFirmwareConfigured(uint8_t result); private: virtual ~VendorInterface() = default; private: bool Open(InitializeCompleteCallback initialize_complete_cb, PacketReadCallback event_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb, PacketReadCallback iso_cb); Loading