1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #include <aidl/android/hardware/bluetooth/BnBluetoothHci.h>
18 #include <aidl/android/hardware/bluetooth/BnBluetoothHciCallbacks.h>
19 #include <aidl/android/hardware/bluetooth/IBluetoothHci.h>
20 #include <android/binder_manager.h>
21 #include <bluetooth/log.h>
22 
23 #include "common/stop_watch.h"
24 #include "hal/hci_backend.h"
25 
26 namespace bluetooth::hal {
27 
28 class AidlHciCallbacks : public ::aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
29  public:
AidlHciCallbacks(std::shared_ptr<HciBackendCallbacks> callbacks)30   AidlHciCallbacks(std::shared_ptr<HciBackendCallbacks> callbacks) : callbacks_(callbacks) {}
31 
32   using AidlStatus = ::aidl::android::hardware::bluetooth::Status;
initializationComplete(AidlStatus status)33   ::ndk::ScopedAStatus initializationComplete(AidlStatus status) override {
34     log::assert_that(status == AidlStatus::SUCCESS, "status == AidlStatus::SUCCESS");
35     callbacks_->initializationComplete();
36     return ::ndk::ScopedAStatus::ok();
37   }
38 
hciEventReceived(const std::vector<uint8_t> & packet)39   ::ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& packet) override {
40     callbacks_->hciEventReceived(packet);
41     return ::ndk::ScopedAStatus::ok();
42   }
43 
aclDataReceived(const std::vector<uint8_t> & packet)44   ::ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& packet) override {
45     callbacks_->aclDataReceived(packet);
46     return ::ndk::ScopedAStatus::ok();
47   }
48 
scoDataReceived(const std::vector<uint8_t> & packet)49   ::ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& packet) override {
50     callbacks_->scoDataReceived(packet);
51     return ::ndk::ScopedAStatus::ok();
52   }
53 
isoDataReceived(const std::vector<uint8_t> & packet)54   ::ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& packet) override {
55     callbacks_->isoDataReceived(packet);
56     return ::ndk::ScopedAStatus::ok();
57   }
58 
59  private:
60   std::shared_ptr<HciBackendCallbacks> callbacks_;
61 };
62 
63 class AidlHci : public HciBackend {
64  public:
AidlHci(const char * service_name)65   AidlHci(const char* service_name) {
66     ::ndk::SpAIBinder binder(AServiceManager_waitForService(service_name));
67     hci_ = aidl::android::hardware::bluetooth::IBluetoothHci::fromBinder(binder);
68     log::assert_that(hci_ != nullptr, "Failed to retrieve AIDL interface.");
69 
70     death_recipient_ =
71         ::ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new([](void* /* cookie*/) {
72           log::error("The Bluetooth HAL service died. Dumping logs and crashing in 1 second.");
73           common::StopWatch::DumpStopWatchLog();
74           // At shutdown, sometimes the HAL service gets killed before Bluetooth.
75           std::this_thread::sleep_for(std::chrono::seconds(1));
76           log::fatal("The Bluetooth HAL died.");
77         }));
78 
79     auto death_link = AIBinder_linkToDeath(hci_->asBinder().get(), death_recipient_.get(), this);
80     log::assert_that(
81         death_link == STATUS_OK, "Unable to set the death recipient for the Bluetooth HAL");
82   }
83 
~AidlHci()84   ~AidlHci() {
85     auto death_unlink =
86         AIBinder_unlinkToDeath(hci_->asBinder().get(), death_recipient_.get(), this);
87     if (death_unlink != STATUS_OK) {
88       log::error("Error unlinking death recipient from the Bluetooth HAL");
89     }
90     auto close_status = hci_->close();
91     if (!close_status.isOk()) {
92       log::error("Error calling close on the Bluetooth HAL");
93     }
94   }
95 
initialize(std::shared_ptr<HciBackendCallbacks> callbacks)96   void initialize(std::shared_ptr<HciBackendCallbacks> callbacks) {
97     hci_callbacks_ = ::ndk::SharedRefBase::make<AidlHciCallbacks>(callbacks);
98     hci_->initialize(hci_callbacks_);
99   }
100 
sendHciCommand(const std::vector<uint8_t> & command)101   void sendHciCommand(const std::vector<uint8_t>& command) override {
102     hci_->sendHciCommand(command);
103   }
104 
sendAclData(const std::vector<uint8_t> & packet)105   void sendAclData(const std::vector<uint8_t>& packet) override {
106     hci_->sendAclData(packet);
107   }
108 
sendScoData(const std::vector<uint8_t> & packet)109   void sendScoData(const std::vector<uint8_t>& packet) override {
110     hci_->sendScoData(packet);
111   }
112 
sendIsoData(const std::vector<uint8_t> & packet)113   void sendIsoData(const std::vector<uint8_t>& packet) override {
114     hci_->sendIsoData(packet);
115   }
116 
117  private:
118   ::ndk::ScopedAIBinder_DeathRecipient death_recipient_;
119   std::shared_ptr<aidl::android::hardware::bluetooth::IBluetoothHci> hci_;
120   std::shared_ptr<AidlHciCallbacks> hci_callbacks_;
121 };
122 
CreateAidl()123 std::shared_ptr<HciBackend> HciBackend::CreateAidl() {
124   static constexpr char kBluetoothAidlHalServiceName[] =
125       "android.hardware.bluetooth.IBluetoothHci/default";
126 
127   if (AServiceManager_isDeclared(kBluetoothAidlHalServiceName))
128     return std::make_shared<AidlHci>(kBluetoothAidlHalServiceName);
129 
130   return std::shared_ptr<HciBackend>();
131 }
132 
133 }  // namespace bluetooth::hal
134