/* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include "common/stop_watch.h" #include "hal/hci_backend.h" namespace bluetooth::hal { class AidlHciCallbacks : public ::aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks { public: AidlHciCallbacks(std::shared_ptr callbacks) : callbacks_(callbacks) {} using AidlStatus = ::aidl::android::hardware::bluetooth::Status; ::ndk::ScopedAStatus initializationComplete(AidlStatus status) override { log::assert_that(status == AidlStatus::SUCCESS, "status == AidlStatus::SUCCESS"); callbacks_->initializationComplete(); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus hciEventReceived(const std::vector& packet) override { callbacks_->hciEventReceived(packet); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus aclDataReceived(const std::vector& packet) override { callbacks_->aclDataReceived(packet); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus scoDataReceived(const std::vector& packet) override { callbacks_->scoDataReceived(packet); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus isoDataReceived(const std::vector& packet) override { callbacks_->isoDataReceived(packet); return ::ndk::ScopedAStatus::ok(); } private: std::shared_ptr callbacks_; }; class AidlHci : public HciBackend { public: AidlHci(const char* service_name) { ::ndk::SpAIBinder binder(AServiceManager_waitForService(service_name)); hci_ = aidl::android::hardware::bluetooth::IBluetoothHci::fromBinder(binder); log::assert_that(hci_ != nullptr, "Failed to retrieve AIDL interface."); death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new([](void* /* cookie*/) { log::error("The Bluetooth HAL service died. Dumping logs and crashing in 1 second."); common::StopWatch::DumpStopWatchLog(); // At shutdown, sometimes the HAL service gets killed before Bluetooth. std::this_thread::sleep_for(std::chrono::seconds(1)); log::fatal("The Bluetooth HAL died."); })); auto death_link = AIBinder_linkToDeath(hci_->asBinder().get(), death_recipient_.get(), this); log::assert_that(death_link == STATUS_OK, "Unable to set the death recipient for the Bluetooth HAL"); } ~AidlHci() { auto death_unlink = AIBinder_unlinkToDeath(hci_->asBinder().get(), death_recipient_.get(), this); if (death_unlink != STATUS_OK) { log::error("Error unlinking death recipient from the Bluetooth HAL"); } auto close_status = hci_->close(); if (!close_status.isOk()) { log::error("Error calling close on the Bluetooth HAL"); } } void initialize(std::shared_ptr callbacks) { hci_callbacks_ = ::ndk::SharedRefBase::make(callbacks); hci_->initialize(hci_callbacks_); } void sendHciCommand(const std::vector& command) override { hci_->sendHciCommand(command); } void sendAclData(const std::vector& packet) override { hci_->sendAclData(packet); } void sendScoData(const std::vector& packet) override { hci_->sendScoData(packet); } void sendIsoData(const std::vector& packet) override { hci_->sendIsoData(packet); } private: ::ndk::ScopedAIBinder_DeathRecipient death_recipient_; std::shared_ptr hci_; std::shared_ptr hci_callbacks_; }; std::shared_ptr HciBackend::CreateAidl() { static constexpr char kBluetoothAidlHalServiceName[] = "android.hardware.bluetooth.IBluetoothHci/default"; if (AServiceManager_isDeclared(kBluetoothAidlHalServiceName)) { return std::make_shared(kBluetoothAidlHalServiceName); } return std::shared_ptr(); } } // namespace bluetooth::hal