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