diff options
author | Myles Watson <mylesgw@google.com> | 2022-10-03 16:27:32 -0700 |
---|---|---|
committer | Myles Watson <mylesgw@google.com> | 2023-01-05 17:09:09 -0800 |
commit | efa25d72874c12e71b2ffcf057ebdb80cb41f55b (patch) | |
tree | 790d6be0e4a4f54bc2f8c7c0fdf07a0b228ed501 /bluetooth/aidl/default/BluetoothHci.cpp | |
parent | 044d5a801a5454d1012f3f8d0b5dedcdc1adc540 (diff) |
bluetooth: Add support for linux bluetooth raw hci sockets
The implementation is imported from
packages/modules/Bluetooth/system/vendor_libs/linux/interface
with modifications to modernize the code.
The default bluetooth HAL implementation now jointly uses
the serial implementation and the bluetooth socket
implementation.
Bug: 205758693
Test: VtsHalBluetoothTargetTest
Change-Id: I791fd406e56a0144e1117cb6f8e27ec71b48a192
Diffstat (limited to 'bluetooth/aidl/default/BluetoothHci.cpp')
-rw-r--r-- | bluetooth/aidl/default/BluetoothHci.cpp | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp index 4d4896d162..dd102a1596 100644 --- a/bluetooth/aidl/default/BluetoothHci.cpp +++ b/bluetooth/aidl/default/BluetoothHci.cpp @@ -44,6 +44,7 @@ int SetTerminalRaw(int fd) { using namespace ::android::hardware::bluetooth::hci; using namespace ::android::hardware::bluetooth::async; +using aidl::android::hardware::bluetooth::Status; namespace aidl::android::hardware::bluetooth::impl { @@ -97,21 +98,25 @@ BluetoothHci::BluetoothHci(const std::string& dev_path) { mDeathRecipient = std::make_shared<BluetoothDeathRecipient>(this); } -ndk::ScopedAStatus BluetoothHci::initialize( - const std::shared_ptr<IBluetoothHciCallbacks>& cb) { - ALOGI(__func__); - - mFd = open(mDevPath.c_str(), O_RDWR); - if (mFd < 0) { +int BluetoothHci::getFdFromDevPath() { + int fd = open(mDevPath.c_str(), O_RDWR); + if (fd < 0) { ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(), strerror(errno)); - return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE); + return fd; } if (int ret = SetTerminalRaw(mFd) < 0) { ALOGE("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret, strerror(errno)); - return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE); + ::close(fd); + return -1; } + return fd; +} + +ndk::ScopedAStatus BluetoothHci::initialize( + const std::shared_ptr<IBluetoothHciCallbacks>& cb) { + ALOGI(__func__); mCb = cb; if (mCb == nullptr) { @@ -119,16 +124,20 @@ ndk::ScopedAStatus BluetoothHci::initialize( return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE); } - mDeathRecipient->LinkToDeath(mCb); + management_.reset(new NetBluetoothMgmt); + mFd = management_->openHci(); + if (mFd < 0) { + management_.reset(); - auto init_ret = cb->initializationComplete(Status::SUCCESS); - if (!init_ret.isOk()) { - if (!mDeathRecipient->getHasDied()) { - ALOGE("Error sending init callback, but no death notification."); + ALOGI("Unable to open Linux interface, trying default path."); + mFd = getFdFromDevPath(); + if (mFd < 0) { + return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE); } - return ndk::ScopedAStatus::fromServiceSpecificError( - STATUS_FAILED_TRANSACTION); } + + mDeathRecipient->LinkToDeath(mCb); + mH4 = std::make_shared<H4Protocol>( mFd, [](const std::vector<uint8_t>& /* raw_command */) { @@ -152,13 +161,29 @@ ndk::ScopedAStatus BluetoothHci::initialize( }); mFdWatcher.WatchFdForNonBlockingReads(mFd, [this](int) { mH4->OnDataReady(); }); + + ALOGI("initialization complete"); + auto status = mCb->initializationComplete(Status::SUCCESS); + if (!status.isOk()) { + if (!mDeathRecipient->getHasDied()) { + ALOGE("Error sending init callback, but no death notification"); + } + close(); + return ndk::ScopedAStatus::fromServiceSpecificError( + STATUS_FAILED_TRANSACTION); + } + return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus BluetoothHci::close() { ALOGI(__func__); mFdWatcher.StopWatchingFileDescriptors(); - ::close(mFd); + if (management_) { + management_->closeHci(); + } else { + ::close(mFd); + } return ndk::ScopedAStatus::ok(); } |