1 /*
2 * Copyright 2019 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 <stdlib.h>
21
22 #include <future>
23 #include <vector>
24
25 #include "btaa/activity_attribution.h"
26 #include "common/init_flags.h"
27 #include "common/stop_watch.h"
28 #include "common/strings.h"
29 #include "hal/hci_hal.h"
30 #include "hal/snoop_logger.h"
31 #include "os/log.h"
32
33 using ::android::hardware::hidl_vec;
34 using ::android::hardware::Return;
35 using ::android::hardware::Void;
36 using ::android::hardware::bluetooth::V1_1::IBluetoothHci;
37 using ::android::hardware::bluetooth::V1_1::IBluetoothHciCallbacks;
38 using HidlStatus = ::android::hardware::bluetooth::V1_0::Status;
39 using IBluetoothHci_1_0 = ::android::hardware::bluetooth::V1_0::IBluetoothHci;
40
41 namespace bluetooth {
42 namespace hal {
43 namespace {
44
45 class HciDeathRecipient : public ::android::hardware::hidl_death_recipient {
46 public:
serviceDied(uint64_t,const android::wp<::android::hidl::base::V1_0::IBase> &)47 virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
48 LOG_ERROR("Bluetooth HAL service died!");
49 common::StopWatch::DumpStopWatchLog();
50 abort();
51 }
52 };
53
54 android::sp<HciDeathRecipient> hci_death_recipient_ = new HciDeathRecipient();
55
56 template <class VecType>
GetTimerText(const char * func_name,VecType vec)57 std::string GetTimerText(const char* func_name, VecType vec) {
58 return common::StringFormat(
59 "%s: len %zu, 1st 5 bytes '%s'",
60 func_name,
61 vec.size(),
62 common::ToHexString(vec.begin(), std::min(vec.end(), vec.begin() + 5)).c_str());
63 }
64
65 class InternalHciCallbacks : public IBluetoothHciCallbacks {
66 public:
InternalHciCallbacks(activity_attribution::ActivityAttribution * btaa_logger_,SnoopLogger * btsnoop_logger)67 InternalHciCallbacks(activity_attribution::ActivityAttribution* btaa_logger_, SnoopLogger* btsnoop_logger)
68 : btaa_logger_(btaa_logger_), btsnoop_logger_(btsnoop_logger) {
69 init_promise_ = new std::promise<void>();
70 }
71
SetCallback(HciHalCallbacks * callback)72 void SetCallback(HciHalCallbacks* callback) {
73 ASSERT(callback_ == nullptr && callback != nullptr);
74 callback_ = callback;
75 }
76
ResetCallback()77 void ResetCallback() {
78 callback_ = nullptr;
79 }
80
GetInitPromise()81 std::promise<void>* GetInitPromise() {
82 return init_promise_;
83 }
84
initializationComplete(HidlStatus status)85 Return<void> initializationComplete(HidlStatus status) {
86 common::StopWatch(__func__);
87 ASSERT(status == HidlStatus::SUCCESS);
88 init_promise_->set_value();
89 return Void();
90 }
91
hciEventReceived(const hidl_vec<uint8_t> & event)92 Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) override {
93 common::StopWatch(GetTimerText(__func__, event));
94 std::vector<uint8_t> received_hci_packet(event.begin(), event.end());
95 btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT);
96 if (common::init_flags::btaa_hci_is_enabled()) {
97 btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::EVT);
98 }
99 if (callback_ != nullptr) {
100 callback_->hciEventReceived(std::move(received_hci_packet));
101 }
102 return Void();
103 }
104
aclDataReceived(const hidl_vec<uint8_t> & data)105 Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) override {
106 common::StopWatch(GetTimerText(__func__, data));
107 std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
108 btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL);
109 if (common::init_flags::btaa_hci_is_enabled()) {
110 btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::ACL);
111 }
112 if (callback_ != nullptr) {
113 callback_->aclDataReceived(std::move(received_hci_packet));
114 }
115 return Void();
116 }
117
scoDataReceived(const hidl_vec<uint8_t> & data)118 Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) override {
119 common::StopWatch(GetTimerText(__func__, data));
120 std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
121 btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::SCO);
122 if (common::init_flags::btaa_hci_is_enabled()) {
123 btaa_logger_->Capture(received_hci_packet, SnoopLogger::PacketType::SCO);
124 }
125 if (callback_ != nullptr) {
126 callback_->scoDataReceived(std::move(received_hci_packet));
127 }
128 return Void();
129 }
130
isoDataReceived(const hidl_vec<uint8_t> & data)131 Return<void> isoDataReceived(const hidl_vec<uint8_t>& data) override {
132 common::StopWatch(GetTimerText(__func__, data));
133 std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
134 btsnoop_logger_->Capture(received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ISO);
135 if (callback_ != nullptr) {
136 callback_->isoDataReceived(std::move(received_hci_packet));
137 }
138 return Void();
139 }
140
141 private:
142 std::promise<void>* init_promise_ = nullptr;
143 HciHalCallbacks* callback_ = nullptr;
144 activity_attribution::ActivityAttribution* btaa_logger_ = nullptr;
145 SnoopLogger* btsnoop_logger_ = nullptr;
146 };
147
148 } // namespace
149
150 class HciHalHidl : public HciHal {
151 public:
registerIncomingPacketCallback(HciHalCallbacks * callback)152 void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
153 callbacks_->SetCallback(callback);
154 }
155
unregisterIncomingPacketCallback()156 void unregisterIncomingPacketCallback() override {
157 callbacks_->ResetCallback();
158 }
159
sendHciCommand(HciPacket command)160 void sendHciCommand(HciPacket command) override {
161 btsnoop_logger_->Capture(command, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
162 if (common::init_flags::btaa_hci_is_enabled()) {
163 btaa_logger_->Capture(command, SnoopLogger::PacketType::CMD);
164 }
165 bt_hci_->sendHciCommand(command);
166 }
167
sendAclData(HciPacket packet)168 void sendAclData(HciPacket packet) override {
169 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
170 if (common::init_flags::btaa_hci_is_enabled()) {
171 btaa_logger_->Capture(packet, SnoopLogger::PacketType::ACL);
172 }
173 bt_hci_->sendAclData(packet);
174 }
175
sendScoData(HciPacket packet)176 void sendScoData(HciPacket packet) override {
177 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::SCO);
178 if (common::init_flags::btaa_hci_is_enabled()) {
179 btaa_logger_->Capture(packet, SnoopLogger::PacketType::SCO);
180 }
181 bt_hci_->sendScoData(packet);
182 }
183
sendIsoData(HciPacket packet)184 void sendIsoData(HciPacket packet) override {
185 if (bt_hci_1_1_ == nullptr) {
186 LOG_ERROR("ISO is not supported in HAL v1.0");
187 return;
188 }
189
190 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ISO);
191 bt_hci_1_1_->sendIsoData(packet);
192 }
193
194 protected:
ListDependencies(ModuleList * list)195 void ListDependencies(ModuleList* list) override {
196 list->add<SnoopLogger>();
197 if (common::init_flags::btaa_hci_is_enabled()) {
198 list->add<activity_attribution::ActivityAttribution>();
199 }
200 }
201
Start()202 void Start() override {
203 if (common::init_flags::btaa_hci_is_enabled()) {
204 btaa_logger_ = GetDependency<activity_attribution::ActivityAttribution>();
205 }
206 btsnoop_logger_ = GetDependency<SnoopLogger>();
207
208 bt_hci_1_1_ = IBluetoothHci::getService();
209
210 if (bt_hci_1_1_ != nullptr) {
211 bt_hci_ = bt_hci_1_1_;
212 } else {
213 bt_hci_ = IBluetoothHci_1_0::getService();
214 }
215
216 ASSERT(bt_hci_ != nullptr);
217 auto death_link = bt_hci_->linkToDeath(hci_death_recipient_, 0);
218 ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
219 // Block allows allocation of a variable that might be bypassed by goto.
220 {
221 callbacks_ = new InternalHciCallbacks(btaa_logger_, btsnoop_logger_);
222 if (bt_hci_1_1_ != nullptr) {
223 bt_hci_1_1_->initialize_1_1(callbacks_);
224 } else {
225 bt_hci_->initialize(callbacks_);
226 }
227
228 // Don't timeout here, time out at a higher layer
229 callbacks_->GetInitPromise()->get_future().wait();
230 }
231 }
232
Stop()233 void Stop() override {
234 ASSERT(bt_hci_ != nullptr);
235 auto death_unlink = bt_hci_->unlinkToDeath(hci_death_recipient_);
236 if (!death_unlink.isOk()) {
237 LOG_ERROR("Error unlinking death recipient from the Bluetooth HAL");
238 }
239 bt_hci_->close();
240 callbacks_->ResetCallback();
241 bt_hci_ = nullptr;
242 bt_hci_1_1_ = nullptr;
243 }
244
ToString() const245 std::string ToString() const override {
246 return std::string("HciHalHidl");
247 }
248
249 private:
250 android::sp<InternalHciCallbacks> callbacks_;
251 android::sp<IBluetoothHci_1_0> bt_hci_;
252 android::sp<IBluetoothHci> bt_hci_1_1_;
253 activity_attribution::ActivityAttribution* btaa_logger_;
254 SnoopLogger* btsnoop_logger_;
255 };
256
__anon37ce7e190202() 257 const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHidl(); });
258
259 } // namespace hal
260 } // namespace bluetooth
261