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