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 "hal/hci_hal.h"
18
19 #include <stdlib.h>
20 #include <vector>
21 #include <future>
22
23 #include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
24 #include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
25 #include <android/hardware/bluetooth/1.0/types.h>
26
27 #include "hal/snoop_logger.h"
28 #include "os/log.h"
29
30 using ::android::hardware::hidl_vec;
31 using ::android::hardware::Return;
32 using ::android::hardware::Void;
33 using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
34 using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
35 using HidlStatus = ::android::hardware::bluetooth::V1_0::Status;
36
37 namespace bluetooth {
38 namespace hal {
39 namespace {
40
41 class HciDeathRecipient : public ::android::hardware::hidl_death_recipient {
42 public:
serviceDied(uint64_t,const android::wp<::android::hidl::base::V1_0::IBase> &)43 virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
44 LOG_ERROR("Bluetooth HAL service died!");
45 abort();
46 }
47 };
48
49 android::sp<HciDeathRecipient> hci_death_recipient_ = new HciDeathRecipient();
50
51 class InternalHciCallbacks : public IBluetoothHciCallbacks {
52 public:
InternalHciCallbacks(SnoopLogger * btsnoop_logger)53 InternalHciCallbacks(SnoopLogger* btsnoop_logger)
54 : btsnoop_logger_(btsnoop_logger) {
55 init_promise_ = new std::promise<void>();
56 }
57
SetCallback(HciHalCallbacks * callback)58 void SetCallback(HciHalCallbacks* callback) {
59 ASSERT(callback_ == nullptr && callback != nullptr);
60 callback_ = callback;
61 }
62
ResetCallback()63 void ResetCallback() {
64 callback_ = nullptr;
65 }
66
GetInitPromise()67 std::promise<void>* GetInitPromise() {
68 return init_promise_;
69 }
70
initializationComplete(HidlStatus status)71 Return<void> initializationComplete(HidlStatus status) {
72 ASSERT(status == HidlStatus::SUCCESS);
73 init_promise_->set_value();
74 return Void();
75 }
76
hciEventReceived(const hidl_vec<uint8_t> & event)77 Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) {
78 std::vector<uint8_t> received_hci_packet(event.begin(), event.end());
79 btsnoop_logger_->capture(received_hci_packet, SnoopLogger::Direction::INCOMING,
80 SnoopLogger::PacketType::EVT);
81 if (callback_ != nullptr) {
82 callback_->hciEventReceived(std::move(received_hci_packet));
83 }
84 return Void();
85 }
86
aclDataReceived(const hidl_vec<uint8_t> & data)87 Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) {
88 std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
89 btsnoop_logger_->capture(received_hci_packet, SnoopLogger::Direction::INCOMING,
90 SnoopLogger::PacketType::ACL);
91 if (callback_ != nullptr) {
92 callback_->aclDataReceived(std::move(received_hci_packet));
93 }
94 return Void();
95 }
96
scoDataReceived(const hidl_vec<uint8_t> & data)97 Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) {
98 std::vector<uint8_t> received_hci_packet(data.begin(), data.end());
99 btsnoop_logger_->capture(received_hci_packet, SnoopLogger::Direction::INCOMING,
100 SnoopLogger::PacketType::SCO);
101 if (callback_ != nullptr) {
102 callback_->scoDataReceived(std::move(received_hci_packet));
103 }
104 return Void();
105 }
106
107 private:
108 std::promise<void>* init_promise_ = nullptr;
109 HciHalCallbacks* callback_ = nullptr;
110 SnoopLogger* btsnoop_logger_ = nullptr;
111 };
112
113 } // namespace
114
115 const std::string SnoopLogger::DefaultFilePath = "/data/misc/bluetooth/logs/btsnoop_hci.log";
116 const bool SnoopLogger::AlwaysFlush = false;
117
118 class HciHalHidl : public HciHal {
119 public:
registerIncomingPacketCallback(HciHalCallbacks * callback)120 void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
121 callbacks_->SetCallback(callback);
122 }
123
unregisterIncomingPacketCallback()124 void unregisterIncomingPacketCallback() override {
125 callbacks_->ResetCallback();
126 }
127
sendHciCommand(HciPacket command)128 void sendHciCommand(HciPacket command) override {
129 btsnoop_logger_->capture(command, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
130 bt_hci_->sendHciCommand(command);
131 }
132
sendAclData(HciPacket packet)133 void sendAclData(HciPacket packet) override {
134 btsnoop_logger_->capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
135 bt_hci_->sendAclData(packet);
136 }
137
sendScoData(HciPacket packet)138 void sendScoData(HciPacket packet) override {
139 btsnoop_logger_->capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::SCO);
140 bt_hci_->sendScoData(packet);
141 }
142
143 protected:
ListDependencies(ModuleList * list)144 void ListDependencies(ModuleList* list) override {
145 list->add<SnoopLogger>();
146 }
147
Start()148 void Start() override {
149 btsnoop_logger_ = GetDependency<SnoopLogger>();
150 bt_hci_ = IBluetoothHci::getService();
151 ASSERT(bt_hci_ != nullptr);
152 auto death_link = bt_hci_->linkToDeath(hci_death_recipient_, 0);
153 ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
154 // Block allows allocation of a variable that might be bypassed by goto.
155 {
156 callbacks_ = new InternalHciCallbacks(btsnoop_logger_);
157 bt_hci_->initialize(callbacks_);
158 // Don't timeout here, time out at a higher layer
159 callbacks_->GetInitPromise()->get_future().wait();
160 }
161 }
162
Stop()163 void Stop() override {
164 ASSERT(bt_hci_ != nullptr);
165 auto death_unlink = bt_hci_->unlinkToDeath(hci_death_recipient_);
166 if (!death_unlink.isOk()) {
167 LOG_ERROR("Error unlinking death recipient from the Bluetooth HAL");
168 }
169 bt_hci_->close();
170 callbacks_->ResetCallback();
171 bt_hci_ = nullptr;
172 }
173
174 private:
175 android::sp<InternalHciCallbacks> callbacks_;
176 android::sp<IBluetoothHci> bt_hci_;
177 SnoopLogger* btsnoop_logger_;
178 };
179
__anon7c94e5bd0202() 180 const ModuleFactory HciHal::Factory = ModuleFactory([]() {
181 return new HciHalHidl();
182 });
183
184 } // namespace hal
185 } // namespace bluetooth
186