blob: 5ac3afef2c1afddf70ff11c0e32ae81695da5737 [file] [log] [blame]
Myles Watson6d5e7722022-09-30 06:22:43 -07001/*
Antoine SOULIERf0d56e82025-02-26 17:35:45 +00002 * Copyright 2022 The Android Open Source Project
Myles Watson6d5e7722022-09-30 06:22:43 -07003 *
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
Antoine SOULIERf0d56e82025-02-26 17:35:45 +000019#include "BluetoothHci.h"
20
Myles Watson6d5e7722022-09-30 06:22:43 -070021#include <cutils/properties.h>
22#include <fcntl.h>
Antoine SOULIERf0d56e82025-02-26 17:35:45 +000023#include <netdb.h>
24#include <netinet/in.h>
25#include <poll.h>
Myles Watson6d5e7722022-09-30 06:22:43 -070026#include <string.h>
Antoine SOULIERf0d56e82025-02-26 17:35:45 +000027#include <sys/uio.h>
Myles Watson6d5e7722022-09-30 06:22:43 -070028#include <termios.h>
29
30#include "log/log.h"
31
32namespace {
33int SetTerminalRaw(int fd) {
34 termios terminal_settings;
35 int rval = tcgetattr(fd, &terminal_settings);
36 if (rval < 0) {
37 return rval;
38 }
39 cfmakeraw(&terminal_settings);
40 rval = tcsetattr(fd, TCSANOW, &terminal_settings);
41 return rval;
42}
43} // namespace
44
45using namespace ::android::hardware::bluetooth::hci;
46using namespace ::android::hardware::bluetooth::async;
Antoine SOULIER35fef7c2025-02-26 23:01:21 +000047using aidl::android::hardware::bluetooth::hal::Status;
Myles Watson6d5e7722022-09-30 06:22:43 -070048
49namespace aidl::android::hardware::bluetooth::impl {
50
Henri Chataing1267ff22023-08-09 22:38:24 +000051std::optional<std::string> GetSystemProperty(const std::string& property) {
52 std::array<char, PROPERTY_VALUE_MAX> value_array{0};
53 auto value_len = property_get(property.c_str(), value_array.data(), nullptr);
54 if (value_len <= 0) {
55 return std::nullopt;
56 }
57 return std::string(value_array.data(), value_len);
58}
59
60bool starts_with(const std::string& str, const std::string& prefix) {
61 return str.compare(0, prefix.length(), prefix) == 0;
62}
63
Antoine SOULIERf0d56e82025-02-26 17:35:45 +000064BluetoothHci::BluetoothHci(const std::string& dev_path) {
65 char property_bytes[PROPERTY_VALUE_MAX];
66 property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
67 mDevPath = std::string(property_bytes);
Antoine SOULIERf0d56e82025-02-26 17:35:45 +000068}
69
70int BluetoothHci::getFdFromDevPath() {
71 int fd = open(mDevPath.c_str(), O_RDWR);
72 if (fd < 0) {
73 ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
74 strerror(errno));
75 return fd;
76 }
77 if (int ret = SetTerminalRaw(fd) < 0) {
78 ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
79 strerror(errno));
80 }
81 return fd;
82}
83
84void BluetoothHci::reset() {
85 // Send a reset command and wait until the command complete comes back.
86
87 std::vector<uint8_t> reset = {0x03, 0x0c, 0x00};
88
89 auto resetPromise = std::make_shared<std::promise<void>>();
90 auto resetFuture = resetPromise->get_future();
91
92 mH4 = std::make_shared<H4Protocol>(
93 mFd,
94 [](const std::vector<uint8_t>& raw_command) {
95 ALOGI("Discarding %d bytes with command type",
96 static_cast<int>(raw_command.size()));
97 },
98 [](const std::vector<uint8_t>& raw_acl) {
99 ALOGI("Discarding %d bytes with acl type",
100 static_cast<int>(raw_acl.size()));
101 },
102 [](const std::vector<uint8_t>& raw_sco) {
103 ALOGI("Discarding %d bytes with sco type",
104 static_cast<int>(raw_sco.size()));
105 },
106 [resetPromise](const std::vector<uint8_t>& raw_event) {
107 std::vector<uint8_t> reset_complete = {0x0e, 0x04, 0x01,
108 0x03, 0x0c, 0x00};
109 bool valid = raw_event.size() == 6 &&
110 raw_event[0] == reset_complete[0] &&
111 raw_event[1] == reset_complete[1] &&
112 // Don't compare the number of packets field.
113 raw_event[3] == reset_complete[3] &&
114 raw_event[4] == reset_complete[4] &&
115 raw_event[5] == reset_complete[5];
116 if (valid) {
117 resetPromise->set_value();
118 } else {
119 ALOGI("Discarding %d bytes with event type",
120 static_cast<int>(raw_event.size()));
121 }
122 },
123 [](const std::vector<uint8_t>& raw_iso) {
124 ALOGI("Discarding %d bytes with iso type",
125 static_cast<int>(raw_iso.size()));
126 },
127 [this]() {
128 ALOGI("HCI socket device disconnected while waiting for reset");
129 mFdWatcher.StopWatchingFileDescriptors();
130 });
131 mFdWatcher.WatchFdForNonBlockingReads(mFd,
132 [this](int) { mH4->OnDataReady(); });
133
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000134 send(PacketType::COMMAND, reset);
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000135 auto status = resetFuture.wait_for(std::chrono::seconds(1));
136 mFdWatcher.StopWatchingFileDescriptors();
137 if (status == std::future_status::ready) {
138 ALOGI("HCI Reset successful");
139 } else {
140 ALOGE("HCI Reset Response not received in one second");
141 }
142
143 resetPromise.reset();
144}
145
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000146void BluetoothHci::initialize(
147 const std::shared_ptr<hal::IBluetoothHciCallbacks>& cb) {
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000148 ALOGI(__func__);
149
150 if (cb == nullptr) {
151 ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000152 abort();
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000153 }
154
155 HalState old_state = HalState::READY;
156 {
157 std::lock_guard<std::mutex> guard(mStateMutex);
158 if (mState != HalState::READY) {
159 old_state = mState;
160 } else {
161 mState = HalState::INITIALIZING;
162 }
163 }
164
165 if (old_state != HalState::READY) {
166 ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
167 close();
168 cb->initializationComplete(Status::ALREADY_INITIALIZED);
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000169 }
170
171 mCb = cb;
172 management_.reset(new NetBluetoothMgmt);
173 mFd = management_->openHci();
174 if (mFd < 0) {
175 management_.reset();
176
177 ALOGI("Unable to open Linux interface, trying default path.");
178 mFd = getFdFromDevPath();
179 if (mFd < 0) {
180 mState = HalState::READY;
181 cb->initializationComplete(Status::UNABLE_TO_OPEN_INTERFACE);
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000182 }
183 }
184
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000185 // TODO: HCI Reset on emulators since the bluetooth controller
186 // cannot be powered on/off during the HAL setup; and the stack
187 // might received spurious packets/events during boottime.
188 // Proper solution would be to use bt-virtio or vsock to better
189 // control the link to rootcanal and the controller lifetime.
190 const std::string kBoardProperty = "ro.product.board";
191 const std::string kCuttlefishBoard = "cutf";
192 auto board_name = GetSystemProperty(kBoardProperty);
193 if (board_name.has_value() && (
194 starts_with(board_name.value(), "cutf") ||
195 starts_with(board_name.value(), "goldfish"))) {
196 reset();
197 }
198
199 mH4 = std::make_shared<H4Protocol>(
200 mFd,
201 [](const std::vector<uint8_t>& /* raw_command */) {
202 LOG_ALWAYS_FATAL("Unexpected command!");
203 },
204 [this](const std::vector<uint8_t>& raw_acl) {
205 mCb->aclDataReceived(raw_acl);
206 },
207 [this](const std::vector<uint8_t>& raw_sco) {
208 mCb->scoDataReceived(raw_sco);
209 },
210 [this](const std::vector<uint8_t>& raw_event) {
211 mCb->hciEventReceived(raw_event);
212 },
213 [this](const std::vector<uint8_t>& raw_iso) {
214 mCb->isoDataReceived(raw_iso);
215 },
216 [this]() {
217 ALOGI("HCI socket device disconnected");
218 mFdWatcher.StopWatchingFileDescriptors();
219 });
220 mFdWatcher.WatchFdForNonBlockingReads(mFd,
221 [this](int) { mH4->OnDataReady(); });
222
223 {
224 std::lock_guard<std::mutex> guard(mStateMutex);
225 mState = HalState::ONE_CLIENT;
226 }
227 ALOGI("initialization complete");
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000228 mCb->initializationComplete(Status::SUCCESS);
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000229}
230
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000231void BluetoothHci::close() {
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000232 ALOGI(__func__);
233 {
234 std::lock_guard<std::mutex> guard(mStateMutex);
235 if (mState != HalState::ONE_CLIENT) {
236 LOG_ALWAYS_FATAL_IF(mState == HalState::INITIALIZING,
237 "mState is INITIALIZING");
238 ALOGI("Already closed");
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000239 }
240 mState = HalState::CLOSING;
241 }
242
243 mFdWatcher.StopWatchingFileDescriptors();
244
245 if (management_) {
246 management_->closeHci();
247 } else {
248 ::close(mFd);
249 }
250
251 {
252 std::lock_guard<std::mutex> guard(mStateMutex);
253 mState = HalState::READY;
254 mH4 = nullptr;
255 }
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000256}
257
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000258void BluetoothHci::clientDied() {
259 ALOGI(__func__);
260 close();
261}
262
263void BluetoothHci::sendHciCommand(const std::vector<uint8_t>& packet) {
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000264 return send(PacketType::COMMAND, packet);
265}
266
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000267void BluetoothHci::sendAclData(const std::vector<uint8_t>& packet) {
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000268 return send(PacketType::ACL_DATA, packet);
269}
270
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000271void BluetoothHci::sendScoData(const std::vector<uint8_t>& packet) {
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000272 return send(PacketType::SCO_DATA, packet);
273}
274
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000275void BluetoothHci::sendIsoData(const std::vector<uint8_t>& packet) {
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000276 return send(PacketType::ISO_DATA, packet);
277}
278
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000279void BluetoothHci::send(PacketType type, const std::vector<uint8_t>& v) {
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000280 if (v.empty()) {
281 ALOGE("Packet is empty, no data was found to be sent");
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000282 abort();
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000283 }
284
285 std::lock_guard<std::mutex> guard(mStateMutex);
286 if (mH4 == nullptr) {
Antoine SOULIER35fef7c2025-02-26 23:01:21 +0000287 ALOGE("Illegal State");
288 abort();
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000289 }
290
291 mH4->Send(type, v);
Antoine SOULIERf0d56e82025-02-26 17:35:45 +0000292}
293
Myles Watson6d5e7722022-09-30 06:22:43 -0700294} // namespace aidl::android::hardware::bluetooth::impl