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