• 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 <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