1 /*
2 * Copyright (C) 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 <bluetooth/log.h>
18 #include <netdb.h>
19 #include <netinet/in.h>
20 #include <poll.h>
21 #include <sys/socket.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include <chrono>
26 #include <csignal>
27 #include <mutex>
28 #include <queue>
29
30 #include "hal/hci_hal.h"
31 #include "hal/hci_hal_host.h"
32 #include "hal/snoop_logger.h"
33 #include "main/shim/entry.h"
34 #include "metrics/counter_metrics.h"
35 #include "os/reactor.h"
36 #include "os/thread.h"
37
38 namespace {
39 constexpr int INVALID_FD = -1;
40
41 constexpr uint8_t kH4Command = 0x01;
42 constexpr uint8_t kH4Acl = 0x02;
43 constexpr uint8_t kH4Sco = 0x03;
44 constexpr uint8_t kH4Event = 0x04;
45 constexpr uint8_t kH4Iso = 0x05;
46
47 constexpr uint8_t kH4HeaderSize = 1;
48 constexpr uint8_t kHciAclHeaderSize = 4;
49 constexpr uint8_t kHciScoHeaderSize = 3;
50 constexpr uint8_t kHciEvtHeaderSize = 2;
51 constexpr uint8_t kHciIsoHeaderSize = 4;
52 constexpr int kBufSize =
53 1024 + 4 + 1; // DeviceProperties::acl_data_packet_size_ + ACL header + H4 header
54
ConnectToSocket()55 int ConnectToSocket() {
56 auto* config = bluetooth::hal::HciHalHostRootcanalConfig::Get();
57 const std::string& server = config->GetServerAddress();
58 int port = config->GetPort();
59
60 int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
61 if (socket_fd < 1) {
62 bluetooth::log::error("can't create socket: {}", strerror(errno));
63 return INVALID_FD;
64 }
65
66 struct hostent* host;
67 host = gethostbyname(server.c_str());
68 if (host == nullptr) {
69 bluetooth::log::error("can't get server name");
70 return INVALID_FD;
71 }
72
73 struct sockaddr_in serv_addr;
74 memset((void*)&serv_addr, 0, sizeof(serv_addr));
75 serv_addr.sin_family = AF_INET;
76 serv_addr.sin_addr.s_addr = INADDR_ANY;
77 serv_addr.sin_port = htons(port);
78
79 int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
80 if (result < 0) {
81 bluetooth::log::error("can't connect: {}", strerror(errno));
82 return INVALID_FD;
83 }
84
85 timeval socket_timeout{
86 .tv_sec = 3,
87 .tv_usec = 0,
88 };
89 int ret = setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &socket_timeout, sizeof(socket_timeout));
90 if (ret == -1) {
91 bluetooth::log::error("can't control socket fd: {}", strerror(errno));
92 return INVALID_FD;
93 }
94 return socket_fd;
95 }
96 } // namespace
97
98 namespace bluetooth {
99 namespace hal {
100
101 class HciHalHost : public HciHal {
102 public:
registerIncomingPacketCallback(HciHalCallbacks * callback)103 void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
104 std::lock_guard<std::mutex> lock(api_mutex_);
105 log::info("before");
106 {
107 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
108 log::assert_that(
109 incoming_packet_callback_ == nullptr && callback != nullptr,
110 "assert failed: incoming_packet_callback_ == nullptr && callback != nullptr");
111 incoming_packet_callback_ = callback;
112 }
113 log::info("after");
114 }
115
unregisterIncomingPacketCallback()116 void unregisterIncomingPacketCallback() override {
117 std::lock_guard<std::mutex> lock(api_mutex_);
118 log::info("before");
119 {
120 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
121 incoming_packet_callback_ = nullptr;
122 }
123 log::info("after");
124 }
125
sendHciCommand(HciPacket command)126 void sendHciCommand(HciPacket command) override {
127 std::lock_guard<std::mutex> lock(api_mutex_);
128 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
129 std::vector<uint8_t> packet = std::move(command);
130 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
131 SnoopLogger::PacketType::CMD);
132 packet.insert(packet.cbegin(), kH4Command);
133 write_to_fd(packet);
134 }
135
sendAclData(HciPacket data)136 void sendAclData(HciPacket data) override {
137 std::lock_guard<std::mutex> lock(api_mutex_);
138 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
139 std::vector<uint8_t> packet = std::move(data);
140 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
141 SnoopLogger::PacketType::ACL);
142 packet.insert(packet.cbegin(), kH4Acl);
143 write_to_fd(packet);
144 }
145
sendScoData(HciPacket data)146 void sendScoData(HciPacket data) override {
147 std::lock_guard<std::mutex> lock(api_mutex_);
148 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
149 std::vector<uint8_t> packet = std::move(data);
150 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
151 SnoopLogger::PacketType::SCO);
152 packet.insert(packet.cbegin(), kH4Sco);
153 write_to_fd(packet);
154 }
155
sendIsoData(HciPacket data)156 void sendIsoData(HciPacket data) override {
157 std::lock_guard<std::mutex> lock(api_mutex_);
158 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
159 std::vector<uint8_t> packet = std::move(data);
160 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
161 SnoopLogger::PacketType::ISO);
162 packet.insert(packet.cbegin(), kH4Iso);
163 write_to_fd(packet);
164 }
165
166 protected:
ListDependencies(ModuleList *) const167 void ListDependencies(ModuleList* /*list*/) const {}
168
Start()169 void Start() override {
170 std::lock_guard<std::mutex> lock(api_mutex_);
171 log::assert_that(sock_fd_ == INVALID_FD, "assert failed: sock_fd_ == INVALID_FD");
172 sock_fd_ = ConnectToSocket();
173 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
174 reactable_ = hci_incoming_thread_.GetReactor()->Register(
175 sock_fd_, common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)),
176 common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this)));
177 hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
178 os::Reactor::REACT_ON_READ_ONLY);
179 btsnoop_logger_ = shim::GetSnoopLogger();
180 log::info("HAL opened successfully");
181 }
182
Stop()183 void Stop() override {
184 std::lock_guard<std::mutex> lock(api_mutex_);
185 log::info("HAL is closing");
186 if (reactable_ != nullptr) {
187 hci_incoming_thread_.GetReactor()->Unregister(reactable_);
188 log::info("HAL is stopping, start waiting for last callback");
189 // Wait up to 1 second for the last incoming packet callback to finish
190 hci_incoming_thread_.GetReactor()->WaitForUnregisteredReactable(
191 std::chrono::milliseconds(1000));
192 log::info("HAL is stopping, finished waiting for last callback");
193 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
194 }
195 reactable_ = nullptr;
196 {
197 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
198 incoming_packet_callback_ = nullptr;
199 }
200 ::close(sock_fd_);
201 sock_fd_ = INVALID_FD;
202 log::info("HAL is closed");
203 }
204
ToString() const205 std::string ToString() const override { return std::string("HciHalHost"); }
206
207 private:
208 // Held when APIs are called, NOT to be held during callbacks
209 std::mutex api_mutex_;
210 HciHalCallbacks* incoming_packet_callback_ = nullptr;
211 std::mutex incoming_packet_callback_mutex_;
212 int sock_fd_ = INVALID_FD;
213 bluetooth::os::Thread hci_incoming_thread_ =
214 bluetooth::os::Thread("hci_incoming_thread", bluetooth::os::Thread::Priority::NORMAL);
215 bluetooth::os::Reactor::Reactable* reactable_ = nullptr;
216 std::queue<std::vector<uint8_t>> hci_outgoing_queue_;
217 SnoopLogger* btsnoop_logger_ = nullptr;
218
write_to_fd(HciPacket packet)219 void write_to_fd(HciPacket packet) {
220 // TODO: replace this with new queue when it's ready
221 hci_outgoing_queue_.emplace(packet);
222 if (hci_outgoing_queue_.size() == 1) {
223 hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
224 os::Reactor::REACT_ON_READ_WRITE);
225 }
226 }
227
send_packet_ready()228 void send_packet_ready() {
229 std::lock_guard<std::mutex> lock(api_mutex_);
230 if (hci_outgoing_queue_.empty()) {
231 return;
232 }
233 auto packet_to_send = hci_outgoing_queue_.front();
234 auto bytes_written = write(sock_fd_, (void*)packet_to_send.data(), packet_to_send.size());
235 hci_outgoing_queue_.pop();
236 if (bytes_written == -1) {
237 abort();
238 }
239 if (hci_outgoing_queue_.empty()) {
240 hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
241 os::Reactor::REACT_ON_READ_ONLY);
242 }
243 }
244
socketRecvAll(void * buffer,int bufferLen)245 bool socketRecvAll(void* buffer, int bufferLen) {
246 auto buf = static_cast<char*>(buffer);
247 while (bufferLen > 0) {
248 ssize_t ret;
249 RUN_NO_INTR(ret = recv(sock_fd_, buf, bufferLen, 0));
250 if (ret <= 0) {
251 return false;
252 }
253 buf += ret;
254 bufferLen -= ret;
255 }
256 return true;
257 }
258
incoming_packet_received()259 void incoming_packet_received() {
260 {
261 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
262 if (incoming_packet_callback_ == nullptr) {
263 log::info("Dropping a packet");
264 return;
265 }
266 }
267 uint8_t buf[kBufSize] = {};
268
269 ssize_t received_size;
270 RUN_NO_INTR(received_size = recv(sock_fd_, buf, kH4HeaderSize, 0));
271 log::assert_that(received_size != -1, "Can't receive from socket: {}", strerror(errno));
272 if (received_size == 0) {
273 log::warn("Can't read H4 header. EOF received");
274 raise(SIGINT);
275 return;
276 }
277
278 if (buf[0] == kH4Event) {
279 log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciEvtHeaderSize),
280 "Can't receive from socket: {}", strerror(errno));
281
282 uint8_t hci_evt_parameter_total_length = buf[2];
283 log::assert_that(socketRecvAll(buf + kH4HeaderSize + kHciEvtHeaderSize,
284 hci_evt_parameter_total_length),
285 "Can't receive from socket: {}", strerror(errno));
286
287 HciPacket receivedHciPacket;
288 receivedHciPacket.assign(buf + kH4HeaderSize, buf + kH4HeaderSize + kHciEvtHeaderSize +
289 hci_evt_parameter_total_length);
290 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
291 SnoopLogger::PacketType::EVT);
292 {
293 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
294 if (incoming_packet_callback_ == nullptr) {
295 log::info("Dropping an event after processing");
296 return;
297 }
298 incoming_packet_callback_->hciEventReceived(receivedHciPacket);
299 }
300 }
301
302 if (buf[0] == kH4Acl) {
303 log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciAclHeaderSize),
304 "Can't receive from socket: {}", strerror(errno));
305
306 uint16_t hci_acl_data_total_length = (buf[4] << 8) + buf[3];
307 log::assert_that(
308 socketRecvAll(buf + kH4HeaderSize + kHciAclHeaderSize, hci_acl_data_total_length),
309 "Can't receive from socket: {}", strerror(errno));
310
311 HciPacket receivedHciPacket;
312 receivedHciPacket.assign(buf + kH4HeaderSize,
313 buf + kH4HeaderSize + kHciAclHeaderSize + hci_acl_data_total_length);
314 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
315 SnoopLogger::PacketType::ACL);
316 {
317 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
318 if (incoming_packet_callback_ == nullptr) {
319 log::info("Dropping an ACL packet after processing");
320 return;
321 }
322 incoming_packet_callback_->aclDataReceived(receivedHciPacket);
323 }
324 }
325
326 if (buf[0] == kH4Sco) {
327 log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciScoHeaderSize),
328 "Can't receive from socket: {}", strerror(errno));
329
330 uint8_t hci_sco_data_total_length = buf[3];
331 log::assert_that(
332 socketRecvAll(buf + kH4HeaderSize + kHciScoHeaderSize, hci_sco_data_total_length),
333 "Can't receive from socket: {}", strerror(errno));
334
335 HciPacket receivedHciPacket;
336 receivedHciPacket.assign(buf + kH4HeaderSize,
337 buf + kH4HeaderSize + kHciScoHeaderSize + hci_sco_data_total_length);
338 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
339 SnoopLogger::PacketType::SCO);
340 {
341 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
342 if (incoming_packet_callback_ == nullptr) {
343 log::info("Dropping a SCO packet after processing");
344 return;
345 }
346 incoming_packet_callback_->scoDataReceived(receivedHciPacket);
347 }
348 }
349
350 if (buf[0] == kH4Iso) {
351 log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciIsoHeaderSize),
352 "Can't receive from socket: {}", strerror(errno));
353
354 uint16_t hci_iso_data_total_length = ((buf[4] & 0x3f) << 8) + buf[3];
355 log::assert_that(
356 socketRecvAll(buf + kH4HeaderSize + kHciIsoHeaderSize, hci_iso_data_total_length),
357 "Can't receive from socket: {}", strerror(errno));
358
359 HciPacket receivedHciPacket;
360 receivedHciPacket.assign(buf + kH4HeaderSize,
361 buf + kH4HeaderSize + kHciIsoHeaderSize + hci_iso_data_total_length);
362 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
363 SnoopLogger::PacketType::ISO);
364 {
365 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
366 if (incoming_packet_callback_ == nullptr) {
367 log::info("Dropping a ISO packet after processing");
368 return;
369 }
370 incoming_packet_callback_->isoDataReceived(receivedHciPacket);
371 }
372 }
373 memset(buf, 0, kBufSize);
374 }
375 };
376
__anon63c547bd0202() 377 const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHost(); });
378
379 } // namespace hal
380 } // namespace bluetooth
381