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