• 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 <fcntl.h>
21 #include <gtest/gtest.h>
22 #include <netdb.h>
23 #include <netinet/in.h>
24 #include <netinet/ip.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 
29 #include <cstring>
30 #include <queue>
31 #include <thread>
32 #include <utility>
33 #include <vector>
34 
35 #include "com_android_bluetooth_flags.h"
36 #include "hal/hci_hal.h"
37 #include "hal/serialize_packet.h"
38 #include "os/thread.h"
39 #include "os/utils.h"
40 #include "packet/raw_builder.h"
41 
42 using ::bluetooth::os::Thread;
43 
44 namespace bluetooth {
45 namespace hal {
46 namespace {
47 
48 uint16_t kTestPort = 6537;
49 
50 constexpr uint8_t kH4Command = 0x01;
51 constexpr uint8_t kH4Acl = 0x02;
52 constexpr uint8_t kH4Sco = 0x03;
53 constexpr uint8_t kH4Event = 0x04;
54 constexpr uint8_t kH4Iso = 0x05;
55 
56 using H4Packet = std::vector<uint8_t>;
57 
58 std::queue<std::pair<uint8_t, HciPacket>> incoming_packets_queue_;
59 
60 class TestHciHalCallbacks : public HciHalCallbacks {
61 public:
hciEventReceived(HciPacket packet)62   void hciEventReceived(HciPacket packet) override {
63     incoming_packets_queue_.emplace(kH4Event, packet);
64   }
65 
aclDataReceived(HciPacket packet)66   void aclDataReceived(HciPacket packet) override {
67     incoming_packets_queue_.emplace(kH4Acl, packet);
68   }
69 
scoDataReceived(HciPacket packet)70   void scoDataReceived(HciPacket packet) override {
71     incoming_packets_queue_.emplace(kH4Sco, packet);
72   }
73 
isoDataReceived(HciPacket packet)74   void isoDataReceived(HciPacket packet) override {
75     incoming_packets_queue_.emplace(kH4Iso, packet);
76   }
77 };
78 
79 // An implementation of rootcanal desktop HCI server which listens on localhost:kListeningPort
80 class FakeRootcanalDesktopHciServer {
81 public:
FakeRootcanalDesktopHciServer()82   FakeRootcanalDesktopHciServer() {
83     struct sockaddr_in listen_address;
84     socklen_t sockaddr_in_size = sizeof(struct sockaddr_in);
85     memset(&listen_address, 0, sockaddr_in_size);
86 
87     RUN_NO_INTR(listen_fd_ = socket(AF_INET, SOCK_STREAM, 0));
88     if (listen_fd_ < 0) {
89       log::warn("Error creating socket for test channel.");
90       return;
91     }
92 
93     listen_address.sin_family = AF_INET;
94     listen_address.sin_port = htons(HciHalHostRootcanalConfig::Get()->GetPort());
95     listen_address.sin_addr.s_addr = htonl(INADDR_ANY);
96 
97     if (bind(listen_fd_, reinterpret_cast<sockaddr*>(&listen_address), sockaddr_in_size) < 0) {
98       log::warn("Error binding test channel listener socket to address.");
99       close(listen_fd_);
100       return;
101     }
102 
103     if (listen(listen_fd_, 1) < 0) {
104       log::warn("Error listening for test channel.");
105       close(listen_fd_);
106       return;
107     }
108   }
109 
~FakeRootcanalDesktopHciServer()110   ~FakeRootcanalDesktopHciServer() { close(listen_fd_); }
111 
Accept()112   int Accept() {
113     int accept_fd;
114 
115     RUN_NO_INTR(accept_fd = accept(listen_fd_, nullptr, nullptr));
116 
117     int flags = fcntl(accept_fd, F_GETFL, NULL);
118     int ret = fcntl(accept_fd, F_SETFL, flags | O_NONBLOCK);
119     if (ret == -1) {
120       log::error("Can't fcntl");
121       return -1;
122     }
123 
124     if (accept_fd < 0) {
125       log::warn("Error accepting test channel connection errno={} ({}).", errno, strerror(errno));
126 
127       if (errno != EAGAIN && errno != EWOULDBLOCK) {
128         log::error("Closing listen_fd_ (won't try again).");
129         close(listen_fd_);
130         return -1;
131       }
132     }
133 
134     return accept_fd;
135   }
136 
137 private:
138   int listen_fd_ = -1;
139 };
140 
141 class HciHalRootcanalTest : public ::testing::Test {
142 protected:
SetUp()143   void SetUp() override {
144     thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
145     handler_ = new os::Handler(thread_);
146 
147     HciHalHostRootcanalConfig::Get()->SetPort(kTestPort);
148     fake_server_ = new FakeRootcanalDesktopHciServer;
149     hal_ = fake_registry_.Start<HciHal>(thread_, handler_);
150     hal_->registerIncomingPacketCallback(&callbacks_);
151     fake_server_socket_ =
152             fake_server_->Accept();  // accept() after client is connected to avoid blocking
153     std::queue<std::pair<uint8_t, HciPacket>> empty;
154     std::swap(incoming_packets_queue_, empty);
155   }
156 
TearDown()157   void TearDown() override {
158     hal_->unregisterIncomingPacketCallback();
159     handler_->Clear();
160     if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
161       handler_->WaitUntilStopped(bluetooth::kHandlerStopTimeout);
162     }
163     fake_registry_.StopAll();
164     delete handler_;
165     close(fake_server_socket_);
166     delete fake_server_;
167     delete thread_;
168   }
169 
SetFakeServerSocketToBlocking()170   void SetFakeServerSocketToBlocking() {
171     int flags = fcntl(fake_server_socket_, F_GETFL, NULL);
172     int ret = fcntl(fake_server_socket_, F_SETFL, flags & ~O_NONBLOCK);
173     EXPECT_NE(ret, -1) << "Can't set accept fd to blocking";
174   }
175 
176   FakeRootcanalDesktopHciServer* fake_server_ = nullptr;
177   HciHal* hal_ = nullptr;
178   ModuleRegistry fake_registry_;
179   TestHciHalCallbacks callbacks_;
180   int fake_server_socket_ = -1;
181   Thread* thread_;
182   os::Handler* handler_;
183 };
184 
check_packet_equal(std::pair<uint8_t,HciPacket> hci_packet1_type_data_pair,H4Packet h4_packet2)185 void check_packet_equal(std::pair<uint8_t, HciPacket> hci_packet1_type_data_pair,
186                         H4Packet h4_packet2) {
187   auto packet1_hci_size = hci_packet1_type_data_pair.second.size();
188   ASSERT_EQ(packet1_hci_size + 1, h4_packet2.size());
189   ASSERT_EQ(hci_packet1_type_data_pair.first, h4_packet2[0]);
190   ASSERT_EQ(
191           memcmp(hci_packet1_type_data_pair.second.data(), h4_packet2.data() + 1, packet1_hci_size),
192           0);
193 }
194 
make_sample_hci_cmd_pkt(uint8_t parameter_total_length)195 HciPacket make_sample_hci_cmd_pkt(uint8_t parameter_total_length) {
196   HciPacket pkt;
197   pkt.assign(2 + 1 + parameter_total_length, 0x01);
198   pkt[2] = parameter_total_length;
199   return pkt;
200 }
201 
make_sample_hci_acl_pkt(uint8_t payload_size)202 HciPacket make_sample_hci_acl_pkt(uint8_t payload_size) {
203   HciPacket pkt;
204   pkt.assign(2 + 2 + payload_size, 0x01);
205   pkt[2] = payload_size;
206   return pkt;
207 }
208 
make_sample_hci_sco_pkt(uint8_t payload_size)209 HciPacket make_sample_hci_sco_pkt(uint8_t payload_size) {
210   HciPacket pkt;
211   pkt.assign(3 + payload_size, 0x01);
212   pkt[2] = payload_size;
213   return pkt;
214 }
215 
make_sample_h4_evt_pkt(uint8_t parameter_total_length)216 H4Packet make_sample_h4_evt_pkt(uint8_t parameter_total_length) {
217   H4Packet pkt;
218   pkt.assign(1 + 1 + 1 + parameter_total_length, 0x01);
219   pkt[0] = kH4Event;
220   pkt[2] = parameter_total_length;
221   return pkt;
222 }
223 
make_sample_h4_acl_pkt(uint8_t payload_size)224 HciPacket make_sample_h4_acl_pkt(uint8_t payload_size) {
225   HciPacket pkt;
226   pkt.assign(1 + 2 + 2 + payload_size, 0x01);
227   pkt[0] = kH4Acl;
228   pkt[3] = payload_size;
229   pkt[4] = 0;
230   return pkt;
231 }
232 
make_sample_h4_sco_pkt(uint8_t payload_size)233 HciPacket make_sample_h4_sco_pkt(uint8_t payload_size) {
234   HciPacket pkt;
235   pkt.assign(1 + 3 + payload_size, 0x01);
236   pkt[0] = kH4Sco;
237   pkt[3] = payload_size;
238   return pkt;
239 }
240 
make_sample_h4_iso_pkt(uint8_t payload_size)241 HciPacket make_sample_h4_iso_pkt(uint8_t payload_size) {
242   HciPacket pkt;
243   pkt.assign(1 + 4 + payload_size, 0x01);
244   pkt[0] = kH4Iso;
245   pkt[3] = payload_size;
246   pkt[4] = 0;
247   return pkt;
248 }
249 
read_with_retry(int socket,uint8_t * data,size_t length)250 size_t read_with_retry(int socket, uint8_t* data, size_t length) {
251   size_t bytes_read = 0;
252   ssize_t bytes_read_current = 0;
253   do {
254     bytes_read_current = read(socket, data + bytes_read, length - bytes_read);
255     bytes_read += bytes_read_current;
256   } while (length > bytes_read && bytes_read_current > 0);
257   return bytes_read;
258 }
259 
TEST_F(HciHalRootcanalTest,init_and_close)260 TEST_F(HciHalRootcanalTest, init_and_close) {}
261 
TEST_F(HciHalRootcanalTest,receive_hci_evt)262 TEST_F(HciHalRootcanalTest, receive_hci_evt) {
263   H4Packet incoming_packet = make_sample_h4_evt_pkt(3);
264   write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
265   while (incoming_packets_queue_.size() != 1) {
266   }
267   auto packet = incoming_packets_queue_.front();
268   incoming_packets_queue_.pop();
269   check_packet_equal(packet, incoming_packet);
270 }
271 
TEST_F(HciHalRootcanalTest,receive_hci_acl)272 TEST_F(HciHalRootcanalTest, receive_hci_acl) {
273   H4Packet incoming_packet = make_sample_h4_acl_pkt(3);
274   write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
275   while (incoming_packets_queue_.size() != 1) {
276   }
277   auto packet = incoming_packets_queue_.front();
278   incoming_packets_queue_.pop();
279   check_packet_equal(packet, incoming_packet);
280 }
281 
TEST_F(HciHalRootcanalTest,receive_hci_sco)282 TEST_F(HciHalRootcanalTest, receive_hci_sco) {
283   H4Packet incoming_packet = make_sample_h4_sco_pkt(3);
284   write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
285   while (incoming_packets_queue_.size() != 1) {
286   }
287   auto packet = incoming_packets_queue_.front();
288   incoming_packets_queue_.pop();
289   check_packet_equal(packet, incoming_packet);
290 }
291 
TEST_F(HciHalRootcanalTest,receive_hci_iso)292 TEST_F(HciHalRootcanalTest, receive_hci_iso) {
293   H4Packet incoming_packet = make_sample_h4_iso_pkt(3);
294   write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
295   while (incoming_packets_queue_.size() != 1) {
296   }
297   auto packet = incoming_packets_queue_.front();
298   incoming_packets_queue_.pop();
299   check_packet_equal(packet, incoming_packet);
300 }
301 
TEST_F(HciHalRootcanalTest,receive_two_hci_evts)302 TEST_F(HciHalRootcanalTest, receive_two_hci_evts) {
303   H4Packet incoming_packet = make_sample_h4_evt_pkt(3);
304   H4Packet incoming_packet2 = make_sample_h4_evt_pkt(5);
305   write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
306   write(fake_server_socket_, incoming_packet2.data(), incoming_packet2.size());
307   while (incoming_packets_queue_.size() != 2) {
308   }
309   auto packet = incoming_packets_queue_.front();
310   incoming_packets_queue_.pop();
311   check_packet_equal(packet, incoming_packet);
312   packet = incoming_packets_queue_.front();
313   incoming_packets_queue_.pop();
314   check_packet_equal(packet, incoming_packet2);
315 }
316 
TEST_F(HciHalRootcanalTest,receive_evt_and_acl)317 TEST_F(HciHalRootcanalTest, receive_evt_and_acl) {
318   H4Packet incoming_packet = make_sample_h4_evt_pkt(3);
319   H4Packet incoming_packet2 = make_sample_h4_acl_pkt(5);
320   write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
321   write(fake_server_socket_, incoming_packet2.data(), incoming_packet2.size());
322   while (incoming_packets_queue_.size() != 2) {
323   }
324   auto packet = incoming_packets_queue_.front();
325   incoming_packets_queue_.pop();
326   check_packet_equal(packet, incoming_packet);
327   packet = incoming_packets_queue_.front();
328   incoming_packets_queue_.pop();
329   check_packet_equal(packet, incoming_packet2);
330 }
331 
TEST_F(HciHalRootcanalTest,receive_multiple_acl_batch)332 TEST_F(HciHalRootcanalTest, receive_multiple_acl_batch) {
333   H4Packet incoming_packet = make_sample_h4_acl_pkt(5);
334   int num_packets = 1000;
335   for (int i = 0; i < num_packets; i++) {
336     write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
337   }
338   while (incoming_packets_queue_.size() != (size_t)num_packets) {
339   }
340   for (int i = 0; i < num_packets; i++) {
341     auto packet = incoming_packets_queue_.front();
342     incoming_packets_queue_.pop();
343     check_packet_equal(packet, incoming_packet);
344   }
345 }
346 
TEST_F(HciHalRootcanalTest,receive_multiple_acl_sequential)347 TEST_F(HciHalRootcanalTest, receive_multiple_acl_sequential) {
348   H4Packet incoming_packet = make_sample_h4_acl_pkt(5);
349   int num_packets = 1000;
350   for (int i = 0; i < num_packets; i++) {
351     write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
352     while (incoming_packets_queue_.empty()) {
353     }
354     auto packet = incoming_packets_queue_.front();
355     incoming_packets_queue_.pop();
356     check_packet_equal(packet, incoming_packet);
357   }
358 }
359 
TEST_F(HciHalRootcanalTest,send_hci_cmd)360 TEST_F(HciHalRootcanalTest, send_hci_cmd) {
361   uint8_t hci_cmd_param_size = 2;
362   HciPacket hci_data = make_sample_hci_cmd_pkt(hci_cmd_param_size);
363   hal_->sendHciCommand(hci_data);
364   H4Packet read_buf(1 + 2 + 1 + hci_cmd_param_size);
365   SetFakeServerSocketToBlocking();
366   auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
367 
368   ASSERT_EQ(size_read, 1 + hci_data.size());
369   check_packet_equal({kH4Command, hci_data}, read_buf);
370 }
371 
TEST_F(HciHalRootcanalTest,send_acl)372 TEST_F(HciHalRootcanalTest, send_acl) {
373   uint8_t acl_payload_size = 200;
374   HciPacket acl_packet = make_sample_hci_acl_pkt(acl_payload_size);
375   hal_->sendAclData(acl_packet);
376   H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
377   SetFakeServerSocketToBlocking();
378   auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
379 
380   ASSERT_EQ(size_read, 1 + acl_packet.size());
381   check_packet_equal({kH4Acl, acl_packet}, read_buf);
382 }
383 
TEST_F(HciHalRootcanalTest,send_sco)384 TEST_F(HciHalRootcanalTest, send_sco) {
385   uint8_t sco_payload_size = 200;
386   HciPacket sco_packet = make_sample_hci_sco_pkt(sco_payload_size);
387   hal_->sendScoData(sco_packet);
388   H4Packet read_buf(1 + 3 + sco_payload_size);
389   SetFakeServerSocketToBlocking();
390   auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
391 
392   ASSERT_EQ(size_read, 1 + sco_packet.size());
393   check_packet_equal({kH4Sco, sco_packet}, read_buf);
394 }
395 
TEST_F(HciHalRootcanalTest,send_multiple_acl_batch)396 TEST_F(HciHalRootcanalTest, send_multiple_acl_batch) {
397   uint8_t acl_payload_size = 200;
398   int num_packets = 1000;
399   HciPacket acl_packet = make_sample_hci_acl_pkt(acl_payload_size);
400   for (int i = 0; i < num_packets; i++) {
401     hal_->sendAclData(acl_packet);
402   }
403   H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
404   SetFakeServerSocketToBlocking();
405   for (int i = 0; i < num_packets; i++) {
406     auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
407     ASSERT_EQ(size_read, 1 + acl_packet.size());
408     check_packet_equal({kH4Acl, acl_packet}, read_buf);
409   }
410 }
411 
TEST_F(HciHalRootcanalTest,send_multiple_acl_sequential)412 TEST_F(HciHalRootcanalTest, send_multiple_acl_sequential) {
413   uint8_t acl_payload_size = 200;
414   int num_packets = 1000;
415   HciPacket acl_packet = make_sample_hci_acl_pkt(acl_payload_size);
416   SetFakeServerSocketToBlocking();
417   for (int i = 0; i < num_packets; i++) {
418     hal_->sendAclData(acl_packet);
419     H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
420     auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
421     ASSERT_EQ(size_read, 1 + acl_packet.size());
422     check_packet_equal({kH4Acl, acl_packet}, read_buf);
423   }
424 }
425 
TEST(HciHalHidlTest,serialize)426 TEST(HciHalHidlTest, serialize) {
427   std::vector<uint8_t> bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9};
428   auto packet_bytes = hal::SerializePacket(
429           std::unique_ptr<packet::BasePacketBuilder>(new packet::RawBuilder(bytes)));
430   ASSERT_EQ(bytes, packet_bytes);
431 }
432 }  // namespace
433 }  // namespace hal
434 }  // namespace bluetooth
435