blob: 27e6ebfab3783af0b94d78acee5fee264ab79411 [file] [log] [blame]
Dylan Tian8a6e09c2022-08-16 07:29:28 +00001/*
2 * Copyright (C) 2023 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 <aidl/Gtest.h>
18#include <aidl/Vintf.h>
19#include <aidl/android/hardware/bluetooth/BnBluetoothHciCallbacks.h>
20#include <aidl/android/hardware/bluetooth/IBluetoothHci.h>
21#include <aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.h>
22#include <aidl/android/hardware/bluetooth/Status.h>
23#include <android/binder_auto_utils.h>
24#include <android/binder_manager.h>
25#include <android/binder_process.h>
26#include <binder/IServiceManager.h>
27#include <binder/ProcessState.h>
28
29#include <atomic>
30#include <chrono>
31#include <condition_variable>
32#include <future>
33#include <mutex>
34#include <queue>
35#include <thread>
36#include <vector>
37
38using aidl::android::hardware::bluetooth::IBluetoothHci;
39using aidl::android::hardware::bluetooth::IBluetoothHciCallbacks;
40using aidl::android::hardware::bluetooth::Status;
41using ndk::ScopedAStatus;
42using ndk::SpAIBinder;
43
44// Bluetooth Core Specification 3.0 + HS
45static constexpr uint8_t kHciMinimumHciVersion = 5;
46// Bluetooth Core Specification 3.0 + HS
47static constexpr uint8_t kHciMinimumLmpVersion = 5;
48
49static constexpr std::chrono::milliseconds kWaitForInitTimeout(2000);
50static constexpr std::chrono::milliseconds kWaitForHciEventTimeout(2000);
51static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200);
52
53static constexpr uint8_t kCommandHciShouldBeUnknown[] = {
54 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
55static constexpr uint8_t kCommandHciReadLocalVersionInformation[] = {0x01, 0x10,
56 0x00};
57static constexpr uint8_t kCommandHciReadBufferSize[] = {0x05, 0x10, 0x00};
58static constexpr uint8_t kCommandHciReset[] = {0x03, 0x0c, 0x00};
59static constexpr uint8_t kHciStatusSuccess = 0x00;
60static constexpr uint8_t kHciStatusUnknownHciCommand = 0x01;
61
62static constexpr uint8_t kEventCommandComplete = 0x0e;
63static constexpr uint8_t kEventCommandStatus = 0x0f;
64static constexpr uint8_t kEventNumberOfCompletedPackets = 0x13;
65
66static constexpr size_t kEventCodeByte = 0;
67static constexpr size_t kEventCommandStatusStatusByte = 2;
68static constexpr size_t kEventCommandStatusOpcodeLsByte = 4; // Bytes 4 and 5
69static constexpr size_t kEventCommandCompleteOpcodeLsByte = 3; // Bytes 3 and 4
70static constexpr size_t kEventCommandCompleteStatusByte = 5;
71static constexpr size_t kEventCommandCompleteFirstParamByte = 6;
72static constexpr size_t kEventLocalHciVersionByte =
73 kEventCommandCompleteFirstParamByte;
74static constexpr size_t kEventLocalLmpVersionByte =
75 kEventLocalHciVersionByte + 3;
76
77static constexpr size_t kEventNumberOfCompletedPacketsNumHandles = 2;
78
79// To discard Qualcomm ACL debugging
80static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
81
82class ThroughputLogger {
83 public:
84 ThroughputLogger(std::string task)
85 : task_(task), start_time_(std::chrono::steady_clock::now()) {}
86
87 ~ThroughputLogger() {
88 if (total_bytes_ == 0) {
89 return;
90 }
91 std::chrono::duration<double> duration =
92 std::chrono::steady_clock::now() - start_time_;
93 double s = duration.count();
94 if (s == 0) {
95 return;
96 }
97 double rate_kb = (static_cast<double>(total_bytes_) / s) / 1024;
98 ALOGD("%s %.1f KB/s (%zu bytes in %.3fs)", task_.c_str(), rate_kb,
99 total_bytes_, s);
100 }
101
102 void setTotalBytes(size_t total_bytes) { total_bytes_ = total_bytes; }
103
104 private:
105 size_t total_bytes_;
106 std::string task_;
107 std::chrono::steady_clock::time_point start_time_;
108};
109
110// The main test class for Bluetooth HAL.
111class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
112 public:
113 virtual void SetUp() override {
114 // currently test passthrough mode only
115 hci = IBluetoothHci::fromBinder(
116 SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
117 ASSERT_NE(hci, nullptr);
118 ALOGI("%s: getService() for bluetooth hci is %s", __func__,
119 hci->isRemote() ? "remote" : "local");
120
121 // Lambda function
122 auto on_binder_death = [](void* /*cookie*/) { FAIL(); };
123
124 bluetooth_hci_death_recipient =
125 AIBinder_DeathRecipient_new(on_binder_death);
126 ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
127 ASSERT_EQ(STATUS_OK,
128 AIBinder_linkToDeath(hci->asBinder().get(),
129 bluetooth_hci_death_recipient, 0));
130
131 hci_cb = ndk::SharedRefBase::make<BluetoothHciCallbacks>(*this);
132 ASSERT_NE(hci_cb, nullptr);
133
134 max_acl_data_packet_length = 0;
135 max_sco_data_packet_length = 0;
136 max_acl_data_packets = 0;
137 max_sco_data_packets = 0;
138
139 event_cb_count = 0;
140 acl_cb_count = 0;
141 sco_cb_count = 0;
142
143 ASSERT_TRUE(hci->initialize(hci_cb).isOk());
144 auto future = initialized_promise.get_future();
145 auto timeout_status = future.wait_for(kWaitForInitTimeout);
146 ASSERT_EQ(timeout_status, std::future_status::ready);
147 ASSERT_TRUE(future.get());
148 }
149
150 virtual void TearDown() override {
151 ALOGI("TearDown");
152 // Should not be checked in production code
153 ASSERT_TRUE(hci->close().isOk());
154 std::this_thread::sleep_for(kInterfaceCloseDelayMs);
155 handle_no_ops();
156 EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
157 EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
158 EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
159 EXPECT_EQ(static_cast<size_t>(0), iso_queue.size());
160 }
161
162 void setBufferSizes();
163
164 // Helper functions to try to get a handle on verbosity
165 void handle_no_ops();
166 void wait_for_event(bool timeout_is_error);
167 void wait_for_command_complete_event(std::vector<uint8_t> cmd);
168 int wait_for_completed_packets_event(uint16_t handle);
169
170 // A simple test implementation of BluetoothHciCallbacks.
171 class BluetoothHciCallbacks
172 : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
173 BluetoothAidlTest& parent_;
174
175 public:
176 BluetoothHciCallbacks(BluetoothAidlTest& parent) : parent_(parent){};
177
178 virtual ~BluetoothHciCallbacks() = default;
179
180 ndk::ScopedAStatus initializationComplete(Status status) {
181 parent_.initialized_promise.set_value(status == Status::SUCCESS);
182 ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
183 return ScopedAStatus::ok();
184 };
185
186 ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& event) {
187 parent_.event_cb_count++;
188 parent_.event_queue.push(event);
189 ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
190 return ScopedAStatus::ok();
191 };
192
193 ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& data) {
194 parent_.acl_cb_count++;
195 parent_.acl_queue.push(data);
196 return ScopedAStatus::ok();
197 };
198
199 ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& data) {
200 parent_.sco_cb_count++;
201 parent_.sco_queue.push(data);
202 return ScopedAStatus::ok();
203 };
204
205 ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& data) {
206 parent_.iso_cb_count++;
207 parent_.iso_queue.push(data);
208 return ScopedAStatus::ok();
209 };
210 };
211
212 template <class T>
213 class WaitQueue {
214 public:
215 WaitQueue(){};
216
217 virtual ~WaitQueue() = default;
218
219 bool empty() const {
220 std::lock_guard<std::mutex> lock(m_);
221 return q_.empty();
222 };
223
224 size_t size() const {
225 std::lock_guard<std::mutex> lock(m_);
226 return q_.size();
227 };
228
229 void push(const T& v) {
230 std::lock_guard<std::mutex> lock(m_);
231 q_.push(v);
232 ready_.notify_one();
233 };
234
235 bool pop(T& v) {
236 std::lock_guard<std::mutex> lock(m_);
237 if (q_.empty()) {
238 return false;
239 }
240 v = std::move(q_.front());
241 q_.pop();
242 return true;
243 };
244
245 bool front(T& v) {
246 std::lock_guard<std::mutex> lock(m_);
247 if (q_.empty()) {
248 return false;
249 }
250 v = q_.front();
251 return true;
252 };
253
254 void wait() {
255 std::unique_lock<std::mutex> lock(m_);
256 while (q_.empty()) {
257 ready_.wait(lock);
258 }
259 };
260
261 bool waitWithTimeout(std::chrono::milliseconds timeout) {
262 std::unique_lock<std::mutex> lock(m_);
263 while (q_.empty()) {
264 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
265 return false;
266 }
267 }
268 return true;
269 };
270
271 bool tryPopWithTimeout(T& v, std::chrono::milliseconds timeout) {
272 std::unique_lock<std::mutex> lock(m_);
273 while (q_.empty()) {
274 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
275 return false;
276 }
277 }
278 v = std::move(q_.front());
279 q_.pop();
280 return true;
281 };
282
283 private:
284 mutable std::mutex m_;
285 std::queue<T> q_;
286 std::condition_variable_any ready_;
287 };
288
289 std::shared_ptr<IBluetoothHci> hci;
290 std::shared_ptr<BluetoothHciCallbacks> hci_cb;
291 AIBinder_DeathRecipient* bluetooth_hci_death_recipient;
292 WaitQueue<std::vector<uint8_t>> event_queue;
293 WaitQueue<std::vector<uint8_t>> acl_queue;
294 WaitQueue<std::vector<uint8_t>> sco_queue;
295 WaitQueue<std::vector<uint8_t>> iso_queue;
296
297 std::promise<bool> initialized_promise;
298 int event_cb_count;
299 int sco_cb_count;
300 int acl_cb_count;
301 int iso_cb_count;
302
303 int max_acl_data_packet_length;
304 int max_sco_data_packet_length;
305 int max_acl_data_packets;
306 int max_sco_data_packets;
307};
308
309// Discard NO-OPs from the event queue.
310void BluetoothAidlTest::handle_no_ops() {
311 while (!event_queue.empty()) {
312 std::vector<uint8_t> event;
313 event_queue.front(event);
314 ASSERT_GE(event.size(),
315 static_cast<size_t>(kEventCommandCompleteStatusByte));
316 bool event_is_no_op =
317 (event[kEventCodeByte] == kEventCommandComplete) &&
318 (event[kEventCommandCompleteOpcodeLsByte] == 0x00) &&
319 (event[kEventCommandCompleteOpcodeLsByte + 1] == 0x00);
320 event_is_no_op |= (event[kEventCodeByte] == kEventCommandStatus) &&
321 (event[kEventCommandStatusOpcodeLsByte] == 0x00) &&
322 (event[kEventCommandStatusOpcodeLsByte + 1] == 0x00);
323 if (event_is_no_op) {
324 event_queue.pop(event);
325 } else {
326 break;
327 }
328 }
329 // Discard Qualcomm ACL debugging
330 while (!acl_queue.empty()) {
331 std::vector<uint8_t> acl_packet;
332 acl_queue.front(acl_packet);
333 uint16_t connection_handle = acl_packet[1] & 0xF;
334 connection_handle <<= 8;
335 connection_handle |= acl_packet[0];
336 bool packet_is_no_op = connection_handle == kAclHandleQcaDebugMessage;
337 if (packet_is_no_op) {
338 acl_queue.pop(acl_packet);
339 } else {
340 break;
341 }
342 }
343}
344
345// Receive an event, discarding NO-OPs.
346void BluetoothAidlTest::wait_for_event(bool timeout_is_error = true) {
347 if (timeout_is_error) {
348 ASSERT_TRUE(event_queue.waitWithTimeout(kWaitForHciEventTimeout));
349 } else {
350 event_queue.wait();
351 }
352 ASSERT_LT(static_cast<size_t>(0), event_queue.size());
353 if (event_queue.empty()) {
354 // waitWithTimeout timed out
355 return;
356 }
357 handle_no_ops();
358}
359
360// Wait until a command complete is received.
361void BluetoothAidlTest::wait_for_command_complete_event(
362 std::vector<uint8_t> cmd) {
363 wait_for_event();
364 std::vector<uint8_t> event;
365 ASSERT_TRUE(event_queue.pop(event));
366
367 ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
368 ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
369 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
370 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
371 ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
372}
373
374// Send the command to read the controller's buffer sizes.
375void BluetoothAidlTest::setBufferSizes() {
376 std::vector<uint8_t> cmd{
377 kCommandHciReadBufferSize,
378 kCommandHciReadBufferSize + sizeof(kCommandHciReadBufferSize)};
379 hci->sendHciCommand(cmd);
380
381 wait_for_event();
382 if (event_queue.empty()) {
383 return;
384 }
385 std::vector<uint8_t> event;
386 ASSERT_TRUE(event_queue.pop(event));
387
388 ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
389 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
390 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
391 ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
392
393 max_acl_data_packet_length =
394 event[kEventCommandCompleteStatusByte + 1] +
395 (event[kEventCommandCompleteStatusByte + 2] << 8);
396 max_sco_data_packet_length = event[kEventCommandCompleteStatusByte + 3];
397 max_acl_data_packets = event[kEventCommandCompleteStatusByte + 4] +
398 (event[kEventCommandCompleteStatusByte + 5] << 8);
399 max_sco_data_packets = event[kEventCommandCompleteStatusByte + 6] +
400 (event[kEventCommandCompleteStatusByte + 7] << 8);
401
402 ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
403 static_cast<int>(max_acl_data_packet_length),
404 static_cast<int>(max_acl_data_packets),
405 static_cast<int>(max_sco_data_packet_length),
406 static_cast<int>(max_sco_data_packets));
407}
408
409// Return the number of completed packets reported by the controller.
410int BluetoothAidlTest::wait_for_completed_packets_event(uint16_t handle) {
411 int packets_processed = 0;
412 wait_for_event(false);
413 if (event_queue.empty()) {
414 ALOGW("%s: waitForBluetoothCallback timed out.", __func__);
415 return packets_processed;
416 }
417 while (!event_queue.empty()) {
418 std::vector<uint8_t> event;
419 EXPECT_TRUE(event_queue.pop(event));
420
421 EXPECT_EQ(kEventNumberOfCompletedPackets, event[kEventCodeByte]);
422 EXPECT_EQ(1, event[kEventNumberOfCompletedPacketsNumHandles]);
423
424 uint16_t event_handle = event[3] + (event[4] << 8);
425 EXPECT_EQ(handle, event_handle);
426
427 packets_processed += event[5] + (event[6] << 8);
428 }
429 return packets_processed;
430}
431
432// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
433TEST_P(BluetoothAidlTest, InitializeAndClose) {}
434
435// Send an HCI Reset with sendHciCommand and wait for a command complete event.
436TEST_P(BluetoothAidlTest, HciReset) {
437 std::vector<uint8_t> reset{kCommandHciReset,
438 kCommandHciReset + sizeof(kCommandHciReset)};
439 hci->sendHciCommand(reset);
440
441 wait_for_command_complete_event(reset);
442}
443
444// Read and check the HCI version of the controller.
445TEST_P(BluetoothAidlTest, HciVersionTest) {
446 std::vector<uint8_t> cmd{kCommandHciReadLocalVersionInformation,
447 kCommandHciReadLocalVersionInformation +
448 sizeof(kCommandHciReadLocalVersionInformation)};
449 hci->sendHciCommand(cmd);
450
451 wait_for_event();
452 if (event_queue.empty()) {
453 return;
454 }
455
456 std::vector<uint8_t> event;
457 ASSERT_TRUE(event_queue.pop(event));
458 ASSERT_GT(event.size(), static_cast<size_t>(kEventLocalLmpVersionByte));
459
460 ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
461 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
462 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
463 ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
464
465 ASSERT_LE(kHciMinimumHciVersion, event[kEventLocalHciVersionByte]);
466 ASSERT_LE(kHciMinimumLmpVersion, event[kEventLocalLmpVersionByte]);
467}
468
469// Send an unknown HCI command and wait for the error message.
470TEST_P(BluetoothAidlTest, HciUnknownCommand) {
471 std::vector<uint8_t> cmd{
472 kCommandHciShouldBeUnknown,
473 kCommandHciShouldBeUnknown + sizeof(kCommandHciShouldBeUnknown)};
474 hci->sendHciCommand(cmd);
475
476 wait_for_event();
477 if (event_queue.empty()) {
478 return;
479 }
480
481 std::vector<uint8_t> event;
482 ASSERT_TRUE(event_queue.pop(event));
483
484 ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
485 if (event[kEventCodeByte] == kEventCommandComplete) {
486 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
487 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
488 ASSERT_EQ(kHciStatusUnknownHciCommand,
489 event[kEventCommandCompleteStatusByte]);
490 } else {
491 ASSERT_EQ(kEventCommandStatus, event[kEventCodeByte]);
492 ASSERT_EQ(cmd[0], event[kEventCommandStatusOpcodeLsByte]);
493 ASSERT_EQ(cmd[1], event[kEventCommandStatusOpcodeLsByte + 1]);
494 ASSERT_EQ(kHciStatusUnknownHciCommand,
495 event[kEventCommandStatusStatusByte]);
496 }
497}
498
499// Set all bits in the event mask
500TEST_P(BluetoothAidlTest, SetEventMask) {
501 std::vector<uint8_t> set_event_mask{
502 0x01, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
503 0xff, 0xff};
504 hci->sendHciCommand({set_event_mask});
505 wait_for_command_complete_event(set_event_mask);
506}
507
508// Set all bits in the LE event mask
509TEST_P(BluetoothAidlTest, SetLeEventMask) {
510 std::vector<uint8_t> set_event_mask{
511 0x20, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
512 0xff, 0xff};
513 hci->sendHciCommand({set_event_mask});
514 wait_for_command_complete_event(set_event_mask);
515}
516
517GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
518INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
519 testing::ValuesIn(android::getAidlHalInstanceNames(
520 IBluetoothHci::descriptor)),
521 android::PrintInstanceNameToString);
522
523int main(int argc, char** argv) {
524 ABinderProcess_startThreadPool();
525 ::testing::InitGoogleTest(&argc, argv);
526 int status = RUN_ALL_TESTS();
527 ALOGI("Test result = %d", status);
528 return status;
529}