• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android/hardware/bluetooth/1.0/types.h>
18 #include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
19 #include <android/hardware/bluetooth/1.1/IBluetoothHciCallbacks.h>
20 #include <bluetooth/log.h>
21 
22 #include "common/init_flags.h"
23 #include "common/stop_watch.h"
24 #include "common/strings.h"
25 #include "hal/hci_backend.h"
26 #include "hal/hci_hal.h"
27 #include "os/alarm.h"
28 #include "os/log.h"
29 #include "os/system_properties.h"
30 
31 using ::android::hardware::hidl_vec;
32 using ::android::hardware::Return;
33 using ::android::hardware::Void;
34 using bluetooth::common::BindOnce;
35 using bluetooth::os::Handler;
36 
37 using IBluetoothHci_1_0 = ::android::hardware::bluetooth::V1_0::IBluetoothHci;
38 using IBluetoothHci_1_1 = ::android::hardware::bluetooth::V1_1::IBluetoothHci;
39 using IBluetoothHciCallbacks_1_1 = ::android::hardware::bluetooth::V1_1::IBluetoothHciCallbacks;
40 
41 namespace bluetooth::hal {
42 
43 class HidlHciCallbacks : public IBluetoothHciCallbacks_1_1 {
44  public:
HidlHciCallbacks(std::shared_ptr<HciBackendCallbacks> callbacks)45   HidlHciCallbacks(std::shared_ptr<HciBackendCallbacks> callbacks) : callbacks_(callbacks) {}
46 
47   using HidlStatus = ::android::hardware::bluetooth::V1_0::Status;
initializationComplete(HidlStatus status)48   Return<void> initializationComplete(HidlStatus status) override {
49     log::assert_that(status == HidlStatus::SUCCESS, "status == HidlStatus::SUCCESS");
50     callbacks_->initializationComplete();
51     return Void();
52   }
53 
hciEventReceived(const hidl_vec<uint8_t> & packet)54   Return<void> hciEventReceived(const hidl_vec<uint8_t>& packet) override {
55     callbacks_->hciEventReceived(packet);
56     return Void();
57   }
58 
aclDataReceived(const hidl_vec<uint8_t> & packet)59   Return<void> aclDataReceived(const hidl_vec<uint8_t>& packet) override {
60     callbacks_->aclDataReceived(packet);
61     return Void();
62   }
63 
scoDataReceived(const hidl_vec<uint8_t> & data)64   Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) override {
65     callbacks_->scoDataReceived(data);
66     return Void();
67   }
68 
isoDataReceived(const hidl_vec<uint8_t> & data)69   Return<void> isoDataReceived(const hidl_vec<uint8_t>& data) override {
70     callbacks_->isoDataReceived(data);
71     return Void();
72   }
73 
74  private:
75   std::shared_ptr<HciBackendCallbacks> callbacks_;
76 };
77 
78 class HidlHci : public HciBackend {
79   class DeathRecipient : public ::android::hardware::hidl_death_recipient {
80    public:
serviceDied(uint64_t,const android::wp<::android::hidl::base::V1_0::IBase> &)81     virtual void serviceDied(
82         uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
83       log::error("The Bluetooth HAL service died. Dumping logs and crashing in 1 second.");
84       common::StopWatch::DumpStopWatchLog();
85       // At shutdown, sometimes the HAL service gets killed before Bluetooth.
86       std::this_thread::sleep_for(std::chrono::seconds(1));
87       log::fatal("The Bluetooth HAL died.");
88     }
89   };
90 
91  public:
HidlHci(Handler * module_handler)92   HidlHci(Handler* module_handler) {
93     log::info("Trying to find a HIDL interface");
94 
95     auto get_service_alarm = new os::Alarm(module_handler);
96     get_service_alarm->Schedule(
97         BindOnce([] {
98           const std::string kBoardProperty = "ro.product.board";
99           const std::string kCuttlefishBoard = "cutf";
100           auto board_name = os::GetSystemProperty(kBoardProperty);
101           bool emulator = board_name.has_value() && board_name.value() == kCuttlefishBoard;
102           if (emulator) {
103             log::error("board_name: {}", board_name.value());
104             log::error(
105                 "Unable to get a Bluetooth service after 500ms, start the HAL before starting "
106                 "Bluetooth");
107             return;
108           }
109           log::fatal(
110               "Unable to get a Bluetooth service after 500ms, start the HAL before starting "
111               "Bluetooth");
112         }),
113         std::chrono::milliseconds(500));
114 
115     hci_1_1_ = IBluetoothHci_1_1::getService();
116     if (hci_1_1_)
117       hci_ = hci_1_1_;
118     else
119       hci_ = IBluetoothHci_1_0::getService();
120 
121     get_service_alarm->Cancel();
122     delete get_service_alarm;
123 
124     log::assert_that(hci_ != nullptr, "assert failed: hci_ != nullptr");
125 
126     death_recipient_ = new DeathRecipient();
127     auto death_link = hci_->linkToDeath(death_recipient_, 0);
128     log::assert_that(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
129   }
130 
~HidlHci()131   ~HidlHci() {
132     log::assert_that(hci_ != nullptr, "assert failed: hci_ != nullptr");
133     auto death_unlink = hci_->unlinkToDeath(death_recipient_);
134     if (!death_unlink.isOk()) {
135       log::error("Error unlinking death recipient from the Bluetooth HAL");
136     }
137     auto close_status = hci_->close();
138     if (!close_status.isOk()) {
139       log::error("Error calling close on the Bluetooth HAL");
140     }
141     hci_ = nullptr;
142     hci_1_1_ = nullptr;
143   }
144 
initialize(std::shared_ptr<HciBackendCallbacks> callbacks)145   void initialize(std::shared_ptr<HciBackendCallbacks> callbacks) override {
146     hci_callbacks_ = new HidlHciCallbacks(callbacks);
147     if (hci_1_1_ != nullptr)
148       hci_1_1_->initialize_1_1(hci_callbacks_);
149     else
150       hci_->initialize(hci_callbacks_);
151   }
152 
sendHciCommand(const std::vector<uint8_t> & command)153   void sendHciCommand(const std::vector<uint8_t>& command) override {
154     hci_->sendHciCommand(command);
155   }
156 
sendAclData(const std::vector<uint8_t> & packet)157   void sendAclData(const std::vector<uint8_t>& packet) override {
158     hci_->sendAclData(packet);
159   }
160 
sendScoData(const std::vector<uint8_t> & packet)161   void sendScoData(const std::vector<uint8_t>& packet) override {
162     hci_->sendScoData(packet);
163   }
164 
sendIsoData(const std::vector<uint8_t> & packet)165   void sendIsoData(const std::vector<uint8_t>& packet) override {
166     if (hci_1_1_ == nullptr) {
167       log::error("ISO is not supported in HAL v1.0");
168       return;
169     }
170     hci_1_1_->sendIsoData(packet);
171   }
172 
173  private:
174   android::sp<DeathRecipient> death_recipient_;
175   android::sp<HidlHciCallbacks> hci_callbacks_;
176   android::sp<IBluetoothHci_1_0> hci_;
177   android::sp<IBluetoothHci_1_1> hci_1_1_;
178 };
179 
CreateHidl(Handler * handler)180 std::shared_ptr<HciBackend> HciBackend::CreateHidl(Handler* handler) {
181   return std::make_shared<HidlHci>(handler);
182 }
183 
184 }  // namespace bluetooth::hal
185