1 /*
2 * Copyright 2022 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 #define LOG_TAG "android.hardware.bluetooth.service.default"
18
19 #include "BluetoothHci.h"
20
21 #include <cutils/properties.h>
22 #include <fcntl.h>
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <poll.h>
26 #include <string.h>
27 #include <sys/uio.h>
28 #include <termios.h>
29
30 #include "log/log.h"
31
32 // TODO: Remove custom logging defines from PDL packets.
33 #undef LOG_INFO
34 #undef LOG_DEBUG
35 #include "hci/hci_packets.h"
36
37 namespace {
SetTerminalRaw(int fd)38 int SetTerminalRaw(int fd) {
39 termios terminal_settings;
40 int rval = tcgetattr(fd, &terminal_settings);
41 if (rval < 0) {
42 return rval;
43 }
44 cfmakeraw(&terminal_settings);
45 rval = tcsetattr(fd, TCSANOW, &terminal_settings);
46 return rval;
47 }
48 } // namespace
49
50 using namespace ::android::hardware::bluetooth::hci;
51 using namespace ::android::hardware::bluetooth::async;
52 using aidl::android::hardware::bluetooth::Status;
53
54 namespace aidl::android::hardware::bluetooth::impl {
55
56 void OnDeath(void* cookie);
57
58 class BluetoothDeathRecipient {
59 public:
BluetoothDeathRecipient(BluetoothHci * hci)60 BluetoothDeathRecipient(BluetoothHci* hci) : mHci(hci) {}
61
LinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks> & cb)62 void LinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
63 mCb = cb;
64 clientDeathRecipient_ = AIBinder_DeathRecipient_new(OnDeath);
65 auto linkToDeathReturnStatus = AIBinder_linkToDeath(
66 mCb->asBinder().get(), clientDeathRecipient_, this /* cookie */);
67 LOG_ALWAYS_FATAL_IF(linkToDeathReturnStatus != STATUS_OK,
68 "Unable to link to death recipient");
69 }
70
UnlinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks> & cb)71 void UnlinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
72 LOG_ALWAYS_FATAL_IF(cb != mCb, "Unable to unlink mismatched pointers");
73 }
74
serviceDied()75 void serviceDied() {
76 if (mCb != nullptr && !AIBinder_isAlive(mCb->asBinder().get())) {
77 ALOGE("Bluetooth remote service has died");
78 } else {
79 ALOGE("BluetoothDeathRecipient::serviceDied called but service not dead");
80 return;
81 }
82 {
83 std::lock_guard<std::mutex> guard(mHasDiedMutex);
84 has_died_ = true;
85 }
86 mHci->close();
87 }
88 BluetoothHci* mHci;
89 std::shared_ptr<IBluetoothHciCallbacks> mCb;
90 AIBinder_DeathRecipient* clientDeathRecipient_;
getHasDied()91 bool getHasDied() {
92 std::lock_guard<std::mutex> guard(mHasDiedMutex);
93 return has_died_;
94 }
95
96 private:
97 std::mutex mHasDiedMutex;
98 bool has_died_{false};
99 };
100
OnDeath(void * cookie)101 void OnDeath(void* cookie) {
102 auto* death_recipient = static_cast<BluetoothDeathRecipient*>(cookie);
103 death_recipient->serviceDied();
104 }
105
BluetoothHci(const std::string & dev_path)106 BluetoothHci::BluetoothHci(const std::string& dev_path) {
107 char property_bytes[PROPERTY_VALUE_MAX];
108 property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
109 mDevPath = std::string(property_bytes);
110 mDeathRecipient = std::make_shared<BluetoothDeathRecipient>(this);
111 }
112
getFdFromDevPath()113 int BluetoothHci::getFdFromDevPath() {
114 int fd = open(mDevPath.c_str(), O_RDWR);
115 if (fd < 0) {
116 ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
117 strerror(errno));
118 return fd;
119 }
120 if (int ret = SetTerminalRaw(fd) < 0) {
121 ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
122 strerror(errno));
123 }
124 return fd;
125 }
126
reset()127 void BluetoothHci::reset() {
128 // Send a reset command and wait until the command complete comes back.
129
130 std::vector<uint8_t> reset;
131 ::bluetooth::packet::BitInserter bi{reset};
132 ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi);
133
134 auto resetPromise = std::make_shared<std::promise<void>>();
135 auto resetFuture = resetPromise->get_future();
136
137 mH4 = std::make_shared<H4Protocol>(
138 mFd,
139 [](const std::vector<uint8_t>& raw_command) {
140 ALOGI("Discarding %d bytes with command type",
141 static_cast<int>(raw_command.size()));
142 },
143 [](const std::vector<uint8_t>& raw_acl) {
144 ALOGI("Discarding %d bytes with acl type",
145 static_cast<int>(raw_acl.size()));
146 },
147 [](const std::vector<uint8_t>& raw_sco) {
148 ALOGI("Discarding %d bytes with sco type",
149 static_cast<int>(raw_sco.size()));
150 },
151 [resetPromise](const std::vector<uint8_t>& raw_event) {
152 bool valid = ::bluetooth::hci::ResetCompleteView::Create(
153 ::bluetooth::hci::CommandCompleteView::Create(
154 ::bluetooth::hci::EventView::Create(
155 ::bluetooth::hci::PacketView<true>(
156 std::make_shared<std::vector<uint8_t>>(
157 raw_event)))))
158 .IsValid();
159 if (valid) {
160 resetPromise->set_value();
161 } else {
162 ALOGI("Discarding %d bytes with event type",
163 static_cast<int>(raw_event.size()));
164 }
165 },
166 [](const std::vector<uint8_t>& raw_iso) {
167 ALOGI("Discarding %d bytes with iso type",
168 static_cast<int>(raw_iso.size()));
169 },
170 [this]() {
171 ALOGI("HCI socket device disconnected while waiting for reset");
172 mFdWatcher.StopWatchingFileDescriptors();
173 });
174 mFdWatcher.WatchFdForNonBlockingReads(mFd,
175 [this](int) { mH4->OnDataReady(); });
176
177 send(PacketType::COMMAND, reset);
178 auto status = resetFuture.wait_for(std::chrono::seconds(1));
179 mFdWatcher.StopWatchingFileDescriptors();
180 if (status == std::future_status::ready) {
181 ALOGI("HCI Reset successful");
182 } else {
183 ALOGE("HCI Reset Response not received in one second");
184 }
185
186 resetPromise.reset();
187 }
188
initialize(const std::shared_ptr<IBluetoothHciCallbacks> & cb)189 ndk::ScopedAStatus BluetoothHci::initialize(
190 const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
191 ALOGI(__func__);
192
193 if (cb == nullptr) {
194 ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
195 return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE);
196 }
197
198 HalState old_state = HalState::READY;
199 {
200 std::lock_guard<std::mutex> guard(mStateMutex);
201 if (mState != HalState::READY) {
202 old_state = mState;
203 } else {
204 mState = HalState::INITIALIZING;
205 }
206 }
207
208 if (old_state != HalState::READY) {
209 ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
210 close();
211 cb->initializationComplete(Status::ALREADY_INITIALIZED);
212 return ndk::ScopedAStatus::ok();
213 }
214
215 mCb = cb;
216 management_.reset(new NetBluetoothMgmt);
217 mFd = management_->openHci();
218 if (mFd < 0) {
219 management_.reset();
220
221 ALOGI("Unable to open Linux interface, trying default path.");
222 mFd = getFdFromDevPath();
223 if (mFd < 0) {
224 cb->initializationComplete(Status::UNABLE_TO_OPEN_INTERFACE);
225 return ndk::ScopedAStatus::ok();
226 }
227 }
228
229 mDeathRecipient->LinkToDeath(mCb);
230
231 // TODO: This should not be necessary when the device implements rfkill.
232 reset();
233
234 mH4 = std::make_shared<H4Protocol>(
235 mFd,
236 [](const std::vector<uint8_t>& /* raw_command */) {
237 LOG_ALWAYS_FATAL("Unexpected command!");
238 },
239 [this](const std::vector<uint8_t>& raw_acl) {
240 mCb->aclDataReceived(raw_acl);
241 },
242 [this](const std::vector<uint8_t>& raw_sco) {
243 mCb->scoDataReceived(raw_sco);
244 },
245 [this](const std::vector<uint8_t>& raw_event) {
246 mCb->hciEventReceived(raw_event);
247 },
248 [this](const std::vector<uint8_t>& raw_iso) {
249 mCb->isoDataReceived(raw_iso);
250 },
251 [this]() {
252 ALOGI("HCI socket device disconnected");
253 mFdWatcher.StopWatchingFileDescriptors();
254 });
255 mFdWatcher.WatchFdForNonBlockingReads(mFd,
256 [this](int) { mH4->OnDataReady(); });
257
258 {
259 std::lock_guard<std::mutex> guard(mStateMutex);
260 mState = HalState::ONE_CLIENT;
261 }
262 ALOGI("initialization complete");
263 auto status = mCb->initializationComplete(Status::SUCCESS);
264 if (!status.isOk()) {
265 if (!mDeathRecipient->getHasDied()) {
266 ALOGE("Error sending init callback, but no death notification");
267 }
268 close();
269 return ndk::ScopedAStatus::fromServiceSpecificError(
270 STATUS_FAILED_TRANSACTION);
271 }
272
273 return ndk::ScopedAStatus::ok();
274 }
275
close()276 ndk::ScopedAStatus BluetoothHci::close() {
277 ALOGI(__func__);
278 {
279 std::lock_guard<std::mutex> guard(mStateMutex);
280 if (mState != HalState::ONE_CLIENT) {
281 ALOGI("Already closed");
282 return ndk::ScopedAStatus::ok();
283 }
284 mState = HalState::CLOSING;
285 }
286
287 mFdWatcher.StopWatchingFileDescriptors();
288
289 if (management_) {
290 management_->closeHci();
291 } else {
292 ::close(mFd);
293 }
294
295 {
296 std::lock_guard<std::mutex> guard(mStateMutex);
297 mState = HalState::READY;
298 }
299 return ndk::ScopedAStatus::ok();
300 }
301
sendHciCommand(const std::vector<uint8_t> & packet)302 ndk::ScopedAStatus BluetoothHci::sendHciCommand(
303 const std::vector<uint8_t>& packet) {
304 send(PacketType::COMMAND, packet);
305 return ndk::ScopedAStatus::ok();
306 }
307
sendAclData(const std::vector<uint8_t> & packet)308 ndk::ScopedAStatus BluetoothHci::sendAclData(
309 const std::vector<uint8_t>& packet) {
310 send(PacketType::ACL_DATA, packet);
311 return ndk::ScopedAStatus::ok();
312 }
313
sendScoData(const std::vector<uint8_t> & packet)314 ndk::ScopedAStatus BluetoothHci::sendScoData(
315 const std::vector<uint8_t>& packet) {
316 send(PacketType::SCO_DATA, packet);
317 return ndk::ScopedAStatus::ok();
318 }
319
sendIsoData(const std::vector<uint8_t> & packet)320 ndk::ScopedAStatus BluetoothHci::sendIsoData(
321 const std::vector<uint8_t>& packet) {
322 send(PacketType::ISO_DATA, packet);
323 return ndk::ScopedAStatus::ok();
324 }
325
send(PacketType type,const std::vector<uint8_t> & v)326 void BluetoothHci::send(PacketType type, const std::vector<uint8_t>& v) {
327 mH4->Send(type, v);
328 }
329
330 } // namespace aidl::android::hardware::bluetooth::impl
331