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 <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 "hal/hci_hal.h"
36 #include "hal/serialize_packet.h"
37 #include "os/log.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() {
111 close(listen_fd_);
112 }
113
Accept()114 int Accept() {
115 int accept_fd;
116
117 RUN_NO_INTR(accept_fd = accept(listen_fd_, nullptr, nullptr));
118
119 int flags = fcntl(accept_fd, F_GETFL, NULL);
120 int ret = fcntl(accept_fd, F_SETFL, flags | O_NONBLOCK);
121 if (ret == -1) {
122 log::error("Can't fcntl");
123 return -1;
124 }
125
126 if (accept_fd < 0) {
127 log::warn("Error accepting test channel connection errno={} ({}).", errno, strerror(errno));
128
129 if (errno != EAGAIN && errno != EWOULDBLOCK) {
130 log::error("Closing listen_fd_ (won't try again).");
131 close(listen_fd_);
132 return -1;
133 }
134 }
135
136 return accept_fd;
137 }
138
139 private:
140 int listen_fd_ = -1;
141 };
142
143 class HciHalRootcanalTest : public ::testing::Test {
144 protected:
SetUp()145 void SetUp() override {
146 thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
147
148 HciHalHostRootcanalConfig::Get()->SetPort(kTestPort);
149 fake_server_ = new FakeRootcanalDesktopHciServer;
150 hal_ = fake_registry_.Start<HciHal>(thread_);
151 hal_->registerIncomingPacketCallback(&callbacks_);
152 fake_server_socket_ = 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 fake_registry_.StopAll();
160 close(fake_server_socket_);
161 delete fake_server_;
162 delete thread_;
163 }
164
SetFakeServerSocketToBlocking()165 void SetFakeServerSocketToBlocking() {
166 int flags = fcntl(fake_server_socket_, F_GETFL, NULL);
167 int ret = fcntl(fake_server_socket_, F_SETFL, flags & ~O_NONBLOCK);
168 EXPECT_NE(ret, -1) << "Can't set accept fd to blocking";
169 }
170
171 FakeRootcanalDesktopHciServer* fake_server_ = nullptr;
172 HciHal* hal_ = nullptr;
173 ModuleRegistry fake_registry_;
174 TestHciHalCallbacks callbacks_;
175 int fake_server_socket_ = -1;
176 Thread* thread_;
177 };
178
check_packet_equal(std::pair<uint8_t,HciPacket> hci_packet1_type_data_pair,H4Packet h4_packet2)179 void check_packet_equal(std::pair<uint8_t, HciPacket> hci_packet1_type_data_pair, H4Packet h4_packet2) {
180 auto packet1_hci_size = hci_packet1_type_data_pair.second.size();
181 ASSERT_EQ(packet1_hci_size + 1, h4_packet2.size());
182 ASSERT_EQ(hci_packet1_type_data_pair.first, h4_packet2[0]);
183 ASSERT_EQ(memcmp(hci_packet1_type_data_pair.second.data(), h4_packet2.data() + 1, packet1_hci_size), 0);
184 }
185
make_sample_hci_cmd_pkt(uint8_t parameter_total_length)186 HciPacket make_sample_hci_cmd_pkt(uint8_t parameter_total_length) {
187 HciPacket pkt;
188 pkt.assign(2 + 1 + parameter_total_length, 0x01);
189 pkt[2] = parameter_total_length;
190 return pkt;
191 }
192
make_sample_hci_acl_pkt(uint8_t payload_size)193 HciPacket make_sample_hci_acl_pkt(uint8_t payload_size) {
194 HciPacket pkt;
195 pkt.assign(2 + 2 + payload_size, 0x01);
196 pkt[2] = payload_size;
197 return pkt;
198 }
199
make_sample_hci_sco_pkt(uint8_t payload_size)200 HciPacket make_sample_hci_sco_pkt(uint8_t payload_size) {
201 HciPacket pkt;
202 pkt.assign(3 + payload_size, 0x01);
203 pkt[2] = payload_size;
204 return pkt;
205 }
206
make_sample_h4_evt_pkt(uint8_t parameter_total_length)207 H4Packet make_sample_h4_evt_pkt(uint8_t parameter_total_length) {
208 H4Packet pkt;
209 pkt.assign(1 + 1 + 1 + parameter_total_length, 0x01);
210 pkt[0] = kH4Event;
211 pkt[2] = parameter_total_length;
212 return pkt;
213 }
214
make_sample_h4_acl_pkt(uint8_t payload_size)215 HciPacket make_sample_h4_acl_pkt(uint8_t payload_size) {
216 HciPacket pkt;
217 pkt.assign(1 + 2 + 2 + payload_size, 0x01);
218 pkt[0] = kH4Acl;
219 pkt[3] = payload_size;
220 pkt[4] = 0;
221 return pkt;
222 }
223
make_sample_h4_sco_pkt(uint8_t payload_size)224 HciPacket make_sample_h4_sco_pkt(uint8_t payload_size) {
225 HciPacket pkt;
226 pkt.assign(1 + 3 + payload_size, 0x01);
227 pkt[0] = kH4Sco;
228 pkt[3] = payload_size;
229 return pkt;
230 }
231
make_sample_h4_iso_pkt(uint8_t payload_size)232 HciPacket make_sample_h4_iso_pkt(uint8_t payload_size) {
233 HciPacket pkt;
234 pkt.assign(1 + 4 + payload_size, 0x01);
235 pkt[0] = kH4Iso;
236 pkt[3] = payload_size;
237 pkt[4] = 0;
238 return pkt;
239 }
240
read_with_retry(int socket,uint8_t * data,size_t length)241 size_t read_with_retry(int socket, uint8_t* data, size_t length) {
242 size_t bytes_read = 0;
243 ssize_t bytes_read_current = 0;
244 do {
245 bytes_read_current = read(socket, data + bytes_read, length - bytes_read);
246 bytes_read += bytes_read_current;
247 } while (length > bytes_read && bytes_read_current > 0);
248 return bytes_read;
249 }
250
TEST_F(HciHalRootcanalTest,init_and_close)251 TEST_F(HciHalRootcanalTest, init_and_close) {}
252
TEST_F(HciHalRootcanalTest,receive_hci_evt)253 TEST_F(HciHalRootcanalTest, receive_hci_evt) {
254 H4Packet incoming_packet = make_sample_h4_evt_pkt(3);
255 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
256 while (incoming_packets_queue_.size() != 1) {
257 }
258 auto packet = incoming_packets_queue_.front();
259 incoming_packets_queue_.pop();
260 check_packet_equal(packet, incoming_packet);
261 }
262
TEST_F(HciHalRootcanalTest,receive_hci_acl)263 TEST_F(HciHalRootcanalTest, receive_hci_acl) {
264 H4Packet incoming_packet = make_sample_h4_acl_pkt(3);
265 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
266 while (incoming_packets_queue_.size() != 1) {
267 }
268 auto packet = incoming_packets_queue_.front();
269 incoming_packets_queue_.pop();
270 check_packet_equal(packet, incoming_packet);
271 }
272
TEST_F(HciHalRootcanalTest,receive_hci_sco)273 TEST_F(HciHalRootcanalTest, receive_hci_sco) {
274 H4Packet incoming_packet = make_sample_h4_sco_pkt(3);
275 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
276 while (incoming_packets_queue_.size() != 1) {
277 }
278 auto packet = incoming_packets_queue_.front();
279 incoming_packets_queue_.pop();
280 check_packet_equal(packet, incoming_packet);
281 }
282
TEST_F(HciHalRootcanalTest,receive_hci_iso)283 TEST_F(HciHalRootcanalTest, receive_hci_iso) {
284 H4Packet incoming_packet = make_sample_h4_iso_pkt(3);
285 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
286 while (incoming_packets_queue_.size() != 1) {
287 }
288 auto packet = incoming_packets_queue_.front();
289 incoming_packets_queue_.pop();
290 check_packet_equal(packet, incoming_packet);
291 }
292
TEST_F(HciHalRootcanalTest,receive_two_hci_evts)293 TEST_F(HciHalRootcanalTest, receive_two_hci_evts) {
294 H4Packet incoming_packet = make_sample_h4_evt_pkt(3);
295 H4Packet incoming_packet2 = make_sample_h4_evt_pkt(5);
296 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
297 write(fake_server_socket_, incoming_packet2.data(), incoming_packet2.size());
298 while (incoming_packets_queue_.size() != 2) {
299 }
300 auto packet = incoming_packets_queue_.front();
301 incoming_packets_queue_.pop();
302 check_packet_equal(packet, incoming_packet);
303 packet = incoming_packets_queue_.front();
304 incoming_packets_queue_.pop();
305 check_packet_equal(packet, incoming_packet2);
306 }
307
TEST_F(HciHalRootcanalTest,receive_evt_and_acl)308 TEST_F(HciHalRootcanalTest, receive_evt_and_acl) {
309 H4Packet incoming_packet = make_sample_h4_evt_pkt(3);
310 H4Packet incoming_packet2 = make_sample_h4_acl_pkt(5);
311 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
312 write(fake_server_socket_, incoming_packet2.data(), incoming_packet2.size());
313 while (incoming_packets_queue_.size() != 2) {
314 }
315 auto packet = incoming_packets_queue_.front();
316 incoming_packets_queue_.pop();
317 check_packet_equal(packet, incoming_packet);
318 packet = incoming_packets_queue_.front();
319 incoming_packets_queue_.pop();
320 check_packet_equal(packet, incoming_packet2);
321 }
322
TEST_F(HciHalRootcanalTest,receive_multiple_acl_batch)323 TEST_F(HciHalRootcanalTest, receive_multiple_acl_batch) {
324 H4Packet incoming_packet = make_sample_h4_acl_pkt(5);
325 int num_packets = 1000;
326 for (int i = 0; i < num_packets; i++) {
327 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
328 }
329 while (incoming_packets_queue_.size() != (size_t)num_packets) {
330 }
331 for (int i = 0; i < num_packets; i++) {
332 auto packet = incoming_packets_queue_.front();
333 incoming_packets_queue_.pop();
334 check_packet_equal(packet, incoming_packet);
335 }
336 }
337
TEST_F(HciHalRootcanalTest,receive_multiple_acl_sequential)338 TEST_F(HciHalRootcanalTest, receive_multiple_acl_sequential) {
339 H4Packet incoming_packet = make_sample_h4_acl_pkt(5);
340 int num_packets = 1000;
341 for (int i = 0; i < num_packets; i++) {
342 write(fake_server_socket_, incoming_packet.data(), incoming_packet.size());
343 while (incoming_packets_queue_.empty()) {
344 }
345 auto packet = incoming_packets_queue_.front();
346 incoming_packets_queue_.pop();
347 check_packet_equal(packet, incoming_packet);
348 }
349 }
350
TEST_F(HciHalRootcanalTest,send_hci_cmd)351 TEST_F(HciHalRootcanalTest, send_hci_cmd) {
352 uint8_t hci_cmd_param_size = 2;
353 HciPacket hci_data = make_sample_hci_cmd_pkt(hci_cmd_param_size);
354 hal_->sendHciCommand(hci_data);
355 H4Packet read_buf(1 + 2 + 1 + hci_cmd_param_size);
356 SetFakeServerSocketToBlocking();
357 auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
358
359 ASSERT_EQ(size_read, 1 + hci_data.size());
360 check_packet_equal({kH4Command, hci_data}, read_buf);
361 }
362
TEST_F(HciHalRootcanalTest,send_acl)363 TEST_F(HciHalRootcanalTest, send_acl) {
364 uint8_t acl_payload_size = 200;
365 HciPacket acl_packet = make_sample_hci_acl_pkt(acl_payload_size);
366 hal_->sendAclData(acl_packet);
367 H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
368 SetFakeServerSocketToBlocking();
369 auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
370
371 ASSERT_EQ(size_read, 1 + acl_packet.size());
372 check_packet_equal({kH4Acl, acl_packet}, read_buf);
373 }
374
TEST_F(HciHalRootcanalTest,send_sco)375 TEST_F(HciHalRootcanalTest, send_sco) {
376 uint8_t sco_payload_size = 200;
377 HciPacket sco_packet = make_sample_hci_sco_pkt(sco_payload_size);
378 hal_->sendScoData(sco_packet);
379 H4Packet read_buf(1 + 3 + sco_payload_size);
380 SetFakeServerSocketToBlocking();
381 auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
382
383 ASSERT_EQ(size_read, 1 + sco_packet.size());
384 check_packet_equal({kH4Sco, sco_packet}, read_buf);
385 }
386
TEST_F(HciHalRootcanalTest,send_multiple_acl_batch)387 TEST_F(HciHalRootcanalTest, send_multiple_acl_batch) {
388 uint8_t acl_payload_size = 200;
389 int num_packets = 1000;
390 HciPacket acl_packet = make_sample_hci_acl_pkt(acl_payload_size);
391 for (int i = 0; i < num_packets; i++) {
392 hal_->sendAclData(acl_packet);
393 }
394 H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
395 SetFakeServerSocketToBlocking();
396 for (int i = 0; i < num_packets; i++) {
397 auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
398 ASSERT_EQ(size_read, 1 + acl_packet.size());
399 check_packet_equal({kH4Acl, acl_packet}, read_buf);
400 }
401 }
402
TEST_F(HciHalRootcanalTest,send_multiple_acl_sequential)403 TEST_F(HciHalRootcanalTest, send_multiple_acl_sequential) {
404 uint8_t acl_payload_size = 200;
405 int num_packets = 1000;
406 HciPacket acl_packet = make_sample_hci_acl_pkt(acl_payload_size);
407 SetFakeServerSocketToBlocking();
408 for (int i = 0; i < num_packets; i++) {
409 hal_->sendAclData(acl_packet);
410 H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
411 auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
412 ASSERT_EQ(size_read, 1 + acl_packet.size());
413 check_packet_equal({kH4Acl, acl_packet}, read_buf);
414 }
415 }
416
TEST(HciHalHidlTest,serialize)417 TEST(HciHalHidlTest, serialize) {
418 std::vector<uint8_t> bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9};
419 auto packet_bytes = hal::SerializePacket(std::unique_ptr<packet::BasePacketBuilder>(new packet::RawBuilder(bytes)));
420 ASSERT_EQ(bytes, packet_bytes);
421 }
422 } // namespace
423 } // namespace hal
424 } // namespace bluetooth
425