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 "hal/hci_hal_host.h"
18
19 #include <bluetooth/log.h>
20 #include <netdb.h>
21 #include <netinet/in.h>
22 #include <poll.h>
23 #include <sys/socket.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26
27 #include <chrono> // NOLINT
28 #include <csignal>
29 #include <cstdint>
30 #include <mutex> // NOLINT
31 #include <queue>
32 #include <utility>
33 #include <vector>
34
35 #include "hal/hci_hal.h"
36 #include "hal/link_clocker.h"
37 #include "hal/snoop_logger.h"
38 #include "main/shim/entry.h"
39 #include "metrics/counter_metrics.h"
40 #include "os/mgmt.h"
41 #include "os/reactor.h"
42 #include "os/thread.h"
43
44 extern int GetAdapterIndex();
45
46 namespace {
47 constexpr int INVALID_FD = -1;
48
49 constexpr uint8_t kH4Command = 0x01;
50 constexpr uint8_t kH4Acl = 0x02;
51 constexpr uint8_t kH4Sco = 0x03;
52 constexpr uint8_t kH4Event = 0x04;
53 constexpr uint8_t kH4Iso = 0x05;
54
55 constexpr uint8_t kH4HeaderSize = 1;
56 constexpr uint8_t kHciAclHeaderSize = 4;
57 constexpr uint8_t kHciScoHeaderSize = 3;
58 constexpr uint8_t kHciEvtHeaderSize = 2;
59 constexpr uint8_t kHciIsoHeaderSize = 4;
60 constexpr int kBufSize =
61 1024 + 4 + 1; // DeviceProperties::acl_data_packet_size_ + ACL header + H4 header
62
63 constexpr uint8_t BTPROTO_HCI = 1;
64 constexpr uint16_t HCI_CHANNEL_USER = 1;
65 constexpr uint16_t HCI_CHANNEL_CONTROL = 3;
66 constexpr uint16_t HCI_DEV_NONE = 0xffff;
67
68 /* reference from <kernel>/include/net/bluetooth/mgmt.h */
69 #define MGMT_OP_INDEX_LIST 0x0003
70 #define MGMT_EV_COMMAND_COMP 0x0001
71 #define MGMT_EV_SIZE_MAX 1024
72 #define REPEAT_ON_INTR(fn) \
73 do { \
74 } while ((fn) == -1 && errno == EINTR)
75
76 struct sockaddr_hci {
77 sa_family_t hci_family;
78 uint16_t hci_dev;
79 uint16_t hci_channel;
80 };
81
82 struct mgmt_pkt {
83 uint16_t opcode;
84 uint16_t index;
85 uint16_t len;
86 uint8_t data[MGMT_EV_SIZE_MAX];
87 } __attribute__((packed));
88
89 struct mgmt_event_read_index {
90 uint16_t cc_opcode;
91 uint8_t status;
92 uint16_t num_intf;
93 uint16_t index[0];
94 } __attribute__((packed));
95
waitHciDev(int hci_interface)96 int waitHciDev(int hci_interface) {
97 struct sockaddr_hci addr;
98 struct pollfd fds[1];
99 struct mgmt_pkt ev;
100 int fd;
101 int ret;
102
103 fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
104 if (fd < 0) {
105 bluetooth::log::error("Bluetooth socket error: {}", strerror(errno));
106 return -1;
107 }
108 memset(&addr, 0, sizeof(addr));
109 addr.hci_family = AF_BLUETOOTH;
110 addr.hci_dev = HCI_DEV_NONE;
111 addr.hci_channel = HCI_CHANNEL_CONTROL;
112
113 ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
114 if (ret < 0) {
115 bluetooth::log::error("HCI Channel Control: {} {}", errno, strerror(errno));
116 close(fd);
117 return -1;
118 }
119
120 fds[0].fd = fd;
121 fds[0].events = POLLIN;
122
123 /* Read Controller Index List Command */
124 ev.opcode = MGMT_OP_INDEX_LIST;
125 ev.index = HCI_DEV_NONE;
126 ev.len = 0;
127
128 ssize_t wrote;
129 REPEAT_ON_INTR(wrote = write(fd, &ev, 6));
130 if (wrote != 6) {
131 bluetooth::log::error("Unable to write mgmt command: {}", strerror(errno));
132 close(fd);
133 return -1;
134 }
135 /* validate mentioned hci interface is present and registered with sock system */
136 while (1) {
137 int n;
138 REPEAT_ON_INTR(n = poll(fds, 1, -1));
139 if (n == -1) {
140 bluetooth::log::error("Poll error: {}", strerror(errno));
141 break;
142 } else if (n == 0) {
143 bluetooth::log::error("Timeout, no HCI device detected");
144 break;
145 }
146
147 if (fds[0].revents & POLLIN) {
148 REPEAT_ON_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
149 if (n < 0) {
150 bluetooth::log::error("Error reading control channel: {}", strerror(errno));
151 break;
152 } else if (n == 0) { // unlikely to happen, just a safeguard.
153 bluetooth::log::error("Error reading control channel: EOF");
154 break;
155 }
156
157 if (ev.opcode == MGMT_EV_COMMAND_COMP) {
158 struct mgmt_event_read_index* cc;
159 int i;
160
161 cc = reinterpret_cast<struct mgmt_event_read_index*>(ev.data);
162
163 if (cc->cc_opcode != MGMT_OP_INDEX_LIST) {
164 continue;
165 }
166
167 // Find the interface in the list of available indices. If unavailable,
168 // the result is -1.
169 ret = -1;
170 if (cc->status == 0) {
171 for (i = 0; i < cc->num_intf; i++) {
172 if (cc->index[i] == hci_interface) {
173 ret = 0;
174 break;
175 }
176 }
177
178 if (ret != 0) {
179 // Chipset might be lost. Wait for index added event.
180 bluetooth::log::error(
181 "MGMT index list returns {} HCI interfaces, but HCI interface({}) is not found",
182 cc->num_intf, hci_interface);
183 }
184 } else {
185 // Unlikely event (probably developer error or driver shut down).
186 bluetooth::log::error("Failed to read index list: status({})", cc->status);
187 }
188
189 // Close and return result of Index List.
190 close(fd);
191 return ret;
192 }
193 }
194 }
195
196 close(fd);
197 return -1;
198 }
199
200 // Connect to Linux HCI socket
ConnectToSocket()201 int ConnectToSocket() {
202 int ret = 0;
203
204 int socket_fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
205 if (socket_fd < 0) {
206 bluetooth::log::error("can't create socket: {}", strerror(errno));
207 return INVALID_FD;
208 }
209
210 // Determine which hci index we should connect to.
211 int hci_interface = GetAdapterIndex();
212
213 if (waitHciDev(hci_interface) != 0) {
214 ::close(socket_fd);
215 return INVALID_FD;
216 }
217
218 struct sockaddr_hci addr;
219 memset(&addr, 0, sizeof(addr));
220 addr.hci_family = AF_BLUETOOTH;
221 addr.hci_dev = hci_interface;
222 addr.hci_channel = HCI_CHANNEL_USER;
223
224 ret = bind(socket_fd, (struct sockaddr*)&addr, sizeof(addr));
225 if (ret < 0) {
226 bluetooth::log::error("HCI Channel Control: {} {}", errno, strerror(errno));
227 ::close(socket_fd);
228 return INVALID_FD;
229 }
230 bluetooth::log::info("HCI device ready");
231 return socket_fd;
232 }
233 } // namespace
234
235 namespace bluetooth {
236 namespace hal {
237
238 class HciHalHost : public HciHal {
239 public:
registerIncomingPacketCallback(HciHalCallbacks * callback)240 void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
241 std::lock_guard<std::mutex> lock(api_mutex_);
242 log::info("before");
243 {
244 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
245 log::assert_that(
246 incoming_packet_callback_ == nullptr && callback != nullptr,
247 "assert failed: incoming_packet_callback_ == nullptr && callback != nullptr");
248 incoming_packet_callback_ = callback;
249 }
250 log::info("after");
251 }
252
unregisterIncomingPacketCallback()253 void unregisterIncomingPacketCallback() override {
254 std::lock_guard<std::mutex> lock(api_mutex_);
255 log::info("before");
256 {
257 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
258 incoming_packet_callback_ = nullptr;
259 }
260 log::info("after");
261 }
262
sendHciCommand(HciPacket command)263 void sendHciCommand(HciPacket command) override {
264 std::lock_guard<std::mutex> lock(api_mutex_);
265 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
266 std::vector<uint8_t> packet = std::move(command);
267 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
268 SnoopLogger::PacketType::CMD);
269 packet.insert(packet.cbegin(), kH4Command);
270 write_to_fd(packet);
271 }
272
sendAclData(HciPacket data)273 void sendAclData(HciPacket data) override {
274 std::lock_guard<std::mutex> lock(api_mutex_);
275 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
276 std::vector<uint8_t> packet = std::move(data);
277 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
278 SnoopLogger::PacketType::ACL);
279 packet.insert(packet.cbegin(), kH4Acl);
280 write_to_fd(packet);
281 }
282
sendScoData(HciPacket data)283 void sendScoData(HciPacket data) override {
284 std::lock_guard<std::mutex> lock(api_mutex_);
285 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
286 std::vector<uint8_t> packet = std::move(data);
287 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
288 SnoopLogger::PacketType::SCO);
289 packet.insert(packet.cbegin(), kH4Sco);
290 write_to_fd(packet);
291 }
292
sendIsoData(HciPacket data)293 void sendIsoData(HciPacket data) override {
294 std::lock_guard<std::mutex> lock(api_mutex_);
295 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
296 std::vector<uint8_t> packet = std::move(data);
297 btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
298 SnoopLogger::PacketType::ISO);
299 packet.insert(packet.cbegin(), kH4Iso);
300 write_to_fd(packet);
301 }
302
getMsftOpcode()303 uint16_t getMsftOpcode() override {
304 return os::Management::getInstance().getVendorSpecificCode(MGMT_VS_OPCODE_MSFT);
305 }
306
307 protected:
ListDependencies(ModuleList * list) const308 void ListDependencies(ModuleList* list) const { list->add<LinkClocker>(); }
309
Start()310 void Start() override {
311 std::lock_guard<std::mutex> lock(api_mutex_);
312 log::assert_that(sock_fd_ == INVALID_FD, "assert failed: sock_fd_ == INVALID_FD");
313 sock_fd_ = ConnectToSocket();
314
315 // We don't want to crash when the chipset is broken.
316 if (sock_fd_ == INVALID_FD) {
317 log::error("Failed to connect to HCI socket. Aborting HAL initialization process.");
318 incoming_packet_callback_->controllerNeedsReset();
319 return;
320 }
321
322 reactable_ = hci_incoming_thread_.GetReactor()->Register(
323 sock_fd_, common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)),
324 common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this)));
325 hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
326 os::Reactor::REACT_ON_READ_ONLY);
327 link_clocker_ = GetDependency<LinkClocker>();
328 btsnoop_logger_ = shim::GetSnoopLogger();
329 log::info("HAL opened successfully");
330 }
331
Stop()332 void Stop() override {
333 std::lock_guard<std::mutex> lock(api_mutex_);
334 log::info("HAL is closing");
335 if (reactable_ != nullptr) {
336 hci_incoming_thread_.GetReactor()->Unregister(reactable_);
337 log::info("HAL is stopping, start waiting for last callback");
338 // Wait up to 1 second for the last incoming packet callback to finish
339 hci_incoming_thread_.GetReactor()->WaitForUnregisteredReactable(
340 std::chrono::milliseconds(1000));
341 log::info("HAL is stopping, finished waiting for last callback");
342 log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
343 }
344 reactable_ = nullptr;
345 {
346 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
347 incoming_packet_callback_ = nullptr;
348 }
349 auto start = std::chrono::high_resolution_clock::now();
350 ::close(sock_fd_);
351 auto end = std::chrono::high_resolution_clock::now();
352 int64_t duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
353 log::info("Spent {} milliseconds on closing socket", duration);
354 sock_fd_ = INVALID_FD;
355 log::info("HAL is closed");
356 }
357
ToString() const358 std::string ToString() const override { return std::string("HciHalHost"); }
359
360 private:
361 // Held when APIs are called, NOT to be held during callbacks
362 std::mutex api_mutex_;
363 HciHalCallbacks* incoming_packet_callback_ = nullptr;
364 std::mutex incoming_packet_callback_mutex_;
365 int sock_fd_ = INVALID_FD;
366 bluetooth::os::Thread hci_incoming_thread_ =
367 bluetooth::os::Thread("hci_incoming_thread", bluetooth::os::Thread::Priority::NORMAL);
368 bluetooth::os::Reactor::Reactable* reactable_ = nullptr;
369 std::queue<std::vector<uint8_t>> hci_outgoing_queue_;
370 SnoopLogger* btsnoop_logger_ = nullptr;
371 LinkClocker* link_clocker_ = nullptr;
372
write_to_fd(HciPacket packet)373 void write_to_fd(HciPacket packet) {
374 // TODO(chromeos-bt-team@): replace this with new queue when it's ready
375 hci_outgoing_queue_.emplace(packet);
376 if (hci_outgoing_queue_.size() == 1) {
377 hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
378 os::Reactor::REACT_ON_READ_WRITE);
379 }
380 }
381
send_packet_ready()382 void send_packet_ready() {
383 std::lock_guard<std::mutex> lock(api_mutex_);
384 if (hci_outgoing_queue_.empty()) {
385 return;
386 }
387 auto packet_to_send = hci_outgoing_queue_.front();
388 auto bytes_written =
389 write(sock_fd_, reinterpret_cast<void*>(packet_to_send.data()), packet_to_send.size());
390 hci_outgoing_queue_.pop();
391 if (bytes_written == -1) {
392 log::error("Can't write to socket: {}", strerror(errno));
393 incoming_packet_callback_->controllerNeedsReset();
394 return;
395 }
396 if (hci_outgoing_queue_.empty()) {
397 hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
398 os::Reactor::REACT_ON_READ_ONLY);
399 }
400 }
401
incoming_packet_received()402 void incoming_packet_received() {
403 {
404 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
405 if (incoming_packet_callback_ == nullptr) {
406 log::info("Dropping a packet");
407 return;
408 }
409 }
410 uint8_t buf[kBufSize] = {};
411
412 ssize_t received_size;
413 RUN_NO_INTR(received_size = read(sock_fd_, buf, kBufSize));
414
415 // we don't want crash when the chipset is broken.
416 if (received_size == -1) {
417 log::error("Can't receive from socket: {}", strerror(errno));
418 incoming_packet_callback_->controllerNeedsReset();
419 return;
420 }
421
422 if (received_size == 0) {
423 log::warn("Can't read H4 header. EOF received");
424 incoming_packet_callback_->controllerNeedsReset();
425 return;
426 }
427
428 if (buf[0] == kH4Event) {
429 log::assert_that(received_size >= kH4HeaderSize + kHciEvtHeaderSize,
430 "Received bad HCI_EVT packet size: {}", received_size);
431 uint8_t hci_evt_parameter_total_length = buf[2];
432 ssize_t payload_size = received_size - (kH4HeaderSize + kHciEvtHeaderSize);
433 log::assert_that(payload_size == hci_evt_parameter_total_length,
434 "malformed HCI event total parameter size received: {} != {}", payload_size,
435 hci_evt_parameter_total_length);
436
437 HciPacket receivedHciPacket;
438 receivedHciPacket.assign(buf + kH4HeaderSize,
439 buf + kH4HeaderSize + kHciEvtHeaderSize + payload_size);
440 link_clocker_->OnHciEvent(receivedHciPacket);
441 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
442 SnoopLogger::PacketType::EVT);
443 {
444 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
445 if (incoming_packet_callback_ == nullptr) {
446 log::info("Dropping an event after processing");
447 return;
448 }
449 incoming_packet_callback_->hciEventReceived(receivedHciPacket);
450 }
451 }
452
453 if (buf[0] == kH4Acl) {
454 log::assert_that(received_size >= kH4HeaderSize + kHciAclHeaderSize,
455 "Received bad HCI_ACL packet size: {}", received_size);
456 int payload_size = received_size - (kH4HeaderSize + kHciAclHeaderSize);
457 uint16_t hci_acl_data_total_length = (buf[4] << 8) + buf[3];
458 log::assert_that(payload_size == hci_acl_data_total_length,
459 "malformed ACL length received: {} != {}", payload_size,
460 hci_acl_data_total_length);
461 log::assert_that(hci_acl_data_total_length <= kBufSize - kH4HeaderSize - kHciAclHeaderSize,
462 "packet too long");
463
464 HciPacket receivedHciPacket;
465 receivedHciPacket.assign(buf + kH4HeaderSize,
466 buf + kH4HeaderSize + kHciAclHeaderSize + payload_size);
467 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
468 SnoopLogger::PacketType::ACL);
469 {
470 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
471 if (incoming_packet_callback_ == nullptr) {
472 log::info("Dropping an ACL packet after processing");
473 return;
474 }
475 incoming_packet_callback_->aclDataReceived(receivedHciPacket);
476 }
477 }
478
479 if (buf[0] == kH4Sco) {
480 log::assert_that(received_size >= kH4HeaderSize + kHciScoHeaderSize,
481 "Received bad HCI_SCO packet size: {}", received_size);
482 int payload_size = received_size - (kH4HeaderSize + kHciScoHeaderSize);
483 uint8_t hci_sco_data_total_length = buf[3];
484 log::assert_that(payload_size == hci_sco_data_total_length,
485 "malformed SCO length received: {} != {}", payload_size,
486 hci_sco_data_total_length);
487
488 HciPacket receivedHciPacket;
489 receivedHciPacket.assign(buf + kH4HeaderSize,
490 buf + kH4HeaderSize + kHciScoHeaderSize + payload_size);
491 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
492 SnoopLogger::PacketType::SCO);
493 {
494 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
495 if (incoming_packet_callback_ == nullptr) {
496 log::info("Dropping a SCO packet after processing");
497 return;
498 }
499 incoming_packet_callback_->scoDataReceived(receivedHciPacket);
500 }
501 }
502
503 if (buf[0] == kH4Iso) {
504 log::assert_that(received_size >= kH4HeaderSize + kHciIsoHeaderSize,
505 "Received bad HCI_ISO packet size: {}", received_size);
506 int payload_size = received_size - (kH4HeaderSize + kHciIsoHeaderSize);
507 uint16_t hci_iso_data_total_length = ((buf[4] & 0x3f) << 8) + buf[3];
508 log::assert_that(payload_size == hci_iso_data_total_length,
509 "malformed ISO length received: {} != {}", payload_size,
510 hci_iso_data_total_length);
511
512 HciPacket receivedHciPacket;
513 receivedHciPacket.assign(buf + kH4HeaderSize,
514 buf + kH4HeaderSize + kHciIsoHeaderSize + payload_size);
515 btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
516 SnoopLogger::PacketType::ISO);
517 {
518 std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
519 if (incoming_packet_callback_ == nullptr) {
520 log::info("Dropping a ISO packet after processing");
521 return;
522 }
523 incoming_packet_callback_->isoDataReceived(receivedHciPacket);
524 }
525 }
526 memset(buf, 0, kBufSize);
527 }
528 };
529
__anon67cbaedb0202() 530 const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHost(); });
531
532 } // namespace hal
533 } // namespace bluetooth
534