• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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