blob: 7b9e211d5bce0c32b88e9b773682ad83538d39fb [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
Myles Watsone1708c82023-01-18 17:07:58 -080049static constexpr size_t kNumHciCommandsBandwidth = 100;
50static constexpr size_t kNumScoPacketsBandwidth = 100;
51static constexpr size_t kNumAclPacketsBandwidth = 100;
Dylan Tian8a6e09c2022-08-16 07:29:28 +000052static constexpr std::chrono::milliseconds kWaitForInitTimeout(2000);
53static constexpr std::chrono::milliseconds kWaitForHciEventTimeout(2000);
Myles Watsone1708c82023-01-18 17:07:58 -080054static constexpr std::chrono::milliseconds kWaitForScoDataTimeout(1000);
55static constexpr std::chrono::milliseconds kWaitForAclDataTimeout(1000);
Dylan Tian8a6e09c2022-08-16 07:29:28 +000056static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200);
57
58static constexpr uint8_t kCommandHciShouldBeUnknown[] = {
59 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
60static constexpr uint8_t kCommandHciReadLocalVersionInformation[] = {0x01, 0x10,
61 0x00};
62static constexpr uint8_t kCommandHciReadBufferSize[] = {0x05, 0x10, 0x00};
Myles Watsone1708c82023-01-18 17:07:58 -080063static constexpr uint8_t kCommandHciWriteLoopbackModeLocal[] = {0x02, 0x18,
64 0x01, 0x01};
Dylan Tian8a6e09c2022-08-16 07:29:28 +000065static constexpr uint8_t kCommandHciReset[] = {0x03, 0x0c, 0x00};
Myles Watsone1708c82023-01-18 17:07:58 -080066static constexpr uint8_t kCommandHciSynchronousFlowControlEnable[] = {
67 0x2f, 0x0c, 0x01, 0x01};
68static constexpr uint8_t kCommandHciWriteLocalName[] = {0x13, 0x0c, 0xf8};
Dylan Tian8a6e09c2022-08-16 07:29:28 +000069static constexpr uint8_t kHciStatusSuccess = 0x00;
70static constexpr uint8_t kHciStatusUnknownHciCommand = 0x01;
71
Myles Watsone1708c82023-01-18 17:07:58 -080072static constexpr uint8_t kEventConnectionComplete = 0x03;
Dylan Tian8a6e09c2022-08-16 07:29:28 +000073static constexpr uint8_t kEventCommandComplete = 0x0e;
74static constexpr uint8_t kEventCommandStatus = 0x0f;
75static constexpr uint8_t kEventNumberOfCompletedPackets = 0x13;
Myles Watsone1708c82023-01-18 17:07:58 -080076static constexpr uint8_t kEventLoopbackCommand = 0x19;
Dylan Tian8a6e09c2022-08-16 07:29:28 +000077
78static constexpr size_t kEventCodeByte = 0;
Myles Watsone1708c82023-01-18 17:07:58 -080079static constexpr size_t kEventLengthByte = 1;
80static constexpr size_t kEventFirstPayloadByte = 2;
Dylan Tian8a6e09c2022-08-16 07:29:28 +000081static constexpr size_t kEventCommandStatusStatusByte = 2;
82static constexpr size_t kEventCommandStatusOpcodeLsByte = 4; // Bytes 4 and 5
83static constexpr size_t kEventCommandCompleteOpcodeLsByte = 3; // Bytes 3 and 4
84static constexpr size_t kEventCommandCompleteStatusByte = 5;
85static constexpr size_t kEventCommandCompleteFirstParamByte = 6;
86static constexpr size_t kEventLocalHciVersionByte =
87 kEventCommandCompleteFirstParamByte;
88static constexpr size_t kEventLocalLmpVersionByte =
89 kEventLocalHciVersionByte + 3;
90
Myles Watsone1708c82023-01-18 17:07:58 -080091static constexpr size_t kEventConnectionCompleteParamLength = 11;
92static constexpr size_t kEventConnectionCompleteType = 11;
93static constexpr size_t kEventConnectionCompleteTypeSco = 0;
94static constexpr size_t kEventConnectionCompleteTypeAcl = 1;
95static constexpr size_t kEventConnectionCompleteHandleLsByte = 3;
96
Dylan Tian8a6e09c2022-08-16 07:29:28 +000097static constexpr size_t kEventNumberOfCompletedPacketsNumHandles = 2;
98
Myles Watsone1708c82023-01-18 17:07:58 -080099static constexpr size_t kAclBroadcastFlagOffset = 6;
100static constexpr uint8_t kAclBroadcastFlagPointToPoint = 0x0;
101static constexpr uint8_t kAclBroadcastPointToPoint =
102 (kAclBroadcastFlagPointToPoint << kAclBroadcastFlagOffset);
103
104static constexpr uint8_t kAclPacketBoundaryFlagOffset = 4;
105static constexpr uint8_t kAclPacketBoundaryFlagFirstAutoFlushable = 0x2;
106static constexpr uint8_t kAclPacketBoundaryFirstAutoFlushable =
107 kAclPacketBoundaryFlagFirstAutoFlushable << kAclPacketBoundaryFlagOffset;
108
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000109// To discard Qualcomm ACL debugging
110static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
111
112class ThroughputLogger {
113 public:
114 ThroughputLogger(std::string task)
Myles Watsone1708c82023-01-18 17:07:58 -0800115 : total_bytes_(0),
116 task_(task),
117 start_time_(std::chrono::steady_clock::now()) {}
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000118
119 ~ThroughputLogger() {
120 if (total_bytes_ == 0) {
121 return;
122 }
123 std::chrono::duration<double> duration =
124 std::chrono::steady_clock::now() - start_time_;
125 double s = duration.count();
126 if (s == 0) {
127 return;
128 }
129 double rate_kb = (static_cast<double>(total_bytes_) / s) / 1024;
130 ALOGD("%s %.1f KB/s (%zu bytes in %.3fs)", task_.c_str(), rate_kb,
131 total_bytes_, s);
132 }
133
134 void setTotalBytes(size_t total_bytes) { total_bytes_ = total_bytes; }
135
136 private:
137 size_t total_bytes_;
138 std::string task_;
139 std::chrono::steady_clock::time_point start_time_;
140};
141
142// The main test class for Bluetooth HAL.
143class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
144 public:
145 virtual void SetUp() override {
146 // currently test passthrough mode only
147 hci = IBluetoothHci::fromBinder(
148 SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
149 ASSERT_NE(hci, nullptr);
150 ALOGI("%s: getService() for bluetooth hci is %s", __func__,
151 hci->isRemote() ? "remote" : "local");
152
153 // Lambda function
154 auto on_binder_death = [](void* /*cookie*/) { FAIL(); };
155
156 bluetooth_hci_death_recipient =
157 AIBinder_DeathRecipient_new(on_binder_death);
158 ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
159 ASSERT_EQ(STATUS_OK,
160 AIBinder_linkToDeath(hci->asBinder().get(),
161 bluetooth_hci_death_recipient, 0));
162
163 hci_cb = ndk::SharedRefBase::make<BluetoothHciCallbacks>(*this);
164 ASSERT_NE(hci_cb, nullptr);
165
166 max_acl_data_packet_length = 0;
167 max_sco_data_packet_length = 0;
168 max_acl_data_packets = 0;
169 max_sco_data_packets = 0;
170
171 event_cb_count = 0;
172 acl_cb_count = 0;
173 sco_cb_count = 0;
174
175 ASSERT_TRUE(hci->initialize(hci_cb).isOk());
176 auto future = initialized_promise.get_future();
177 auto timeout_status = future.wait_for(kWaitForInitTimeout);
178 ASSERT_EQ(timeout_status, std::future_status::ready);
179 ASSERT_TRUE(future.get());
180 }
181
182 virtual void TearDown() override {
183 ALOGI("TearDown");
184 // Should not be checked in production code
185 ASSERT_TRUE(hci->close().isOk());
186 std::this_thread::sleep_for(kInterfaceCloseDelayMs);
187 handle_no_ops();
Myles Watsone1708c82023-01-18 17:07:58 -0800188 discard_qca_debugging();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000189 EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
190 EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
191 EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
192 EXPECT_EQ(static_cast<size_t>(0), iso_queue.size());
193 }
194
195 void setBufferSizes();
Myles Watsone1708c82023-01-18 17:07:58 -0800196 void setSynchronousFlowControlEnable();
197
198 // Functions called from within tests in loopback mode
199 void sendAndCheckHci(int num_packets);
200 void sendAndCheckSco(int num_packets, size_t size, uint16_t handle);
201 void sendAndCheckAcl(int num_packets, size_t size, uint16_t handle);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000202
203 // Helper functions to try to get a handle on verbosity
Myles Watsone1708c82023-01-18 17:07:58 -0800204 void enterLoopbackMode();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000205 void handle_no_ops();
Myles Watsone1708c82023-01-18 17:07:58 -0800206 void discard_qca_debugging();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000207 void wait_for_event(bool timeout_is_error);
208 void wait_for_command_complete_event(std::vector<uint8_t> cmd);
209 int wait_for_completed_packets_event(uint16_t handle);
210
211 // A simple test implementation of BluetoothHciCallbacks.
212 class BluetoothHciCallbacks
213 : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
214 BluetoothAidlTest& parent_;
215
216 public:
217 BluetoothHciCallbacks(BluetoothAidlTest& parent) : parent_(parent){};
218
219 virtual ~BluetoothHciCallbacks() = default;
220
221 ndk::ScopedAStatus initializationComplete(Status status) {
222 parent_.initialized_promise.set_value(status == Status::SUCCESS);
223 ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
224 return ScopedAStatus::ok();
225 };
226
227 ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& event) {
228 parent_.event_cb_count++;
229 parent_.event_queue.push(event);
230 ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
231 return ScopedAStatus::ok();
232 };
233
234 ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& data) {
235 parent_.acl_cb_count++;
236 parent_.acl_queue.push(data);
237 return ScopedAStatus::ok();
238 };
239
240 ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& data) {
241 parent_.sco_cb_count++;
242 parent_.sco_queue.push(data);
243 return ScopedAStatus::ok();
244 };
245
246 ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& data) {
247 parent_.iso_cb_count++;
248 parent_.iso_queue.push(data);
249 return ScopedAStatus::ok();
250 };
251 };
252
253 template <class T>
254 class WaitQueue {
255 public:
256 WaitQueue(){};
257
258 virtual ~WaitQueue() = default;
259
260 bool empty() const {
261 std::lock_guard<std::mutex> lock(m_);
262 return q_.empty();
263 };
264
265 size_t size() const {
266 std::lock_guard<std::mutex> lock(m_);
267 return q_.size();
268 };
269
270 void push(const T& v) {
271 std::lock_guard<std::mutex> lock(m_);
272 q_.push(v);
273 ready_.notify_one();
274 };
275
276 bool pop(T& v) {
277 std::lock_guard<std::mutex> lock(m_);
278 if (q_.empty()) {
279 return false;
280 }
281 v = std::move(q_.front());
282 q_.pop();
283 return true;
284 };
285
286 bool front(T& v) {
287 std::lock_guard<std::mutex> lock(m_);
288 if (q_.empty()) {
289 return false;
290 }
291 v = q_.front();
292 return true;
293 };
294
295 void wait() {
296 std::unique_lock<std::mutex> lock(m_);
297 while (q_.empty()) {
298 ready_.wait(lock);
299 }
300 };
301
302 bool waitWithTimeout(std::chrono::milliseconds timeout) {
303 std::unique_lock<std::mutex> lock(m_);
304 while (q_.empty()) {
305 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
306 return false;
307 }
308 }
309 return true;
310 };
311
312 bool tryPopWithTimeout(T& v, std::chrono::milliseconds timeout) {
313 std::unique_lock<std::mutex> lock(m_);
314 while (q_.empty()) {
315 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
316 return false;
317 }
318 }
319 v = std::move(q_.front());
320 q_.pop();
321 return true;
322 };
323
324 private:
325 mutable std::mutex m_;
326 std::queue<T> q_;
327 std::condition_variable_any ready_;
328 };
329
330 std::shared_ptr<IBluetoothHci> hci;
331 std::shared_ptr<BluetoothHciCallbacks> hci_cb;
332 AIBinder_DeathRecipient* bluetooth_hci_death_recipient;
333 WaitQueue<std::vector<uint8_t>> event_queue;
334 WaitQueue<std::vector<uint8_t>> acl_queue;
335 WaitQueue<std::vector<uint8_t>> sco_queue;
336 WaitQueue<std::vector<uint8_t>> iso_queue;
337
338 std::promise<bool> initialized_promise;
339 int event_cb_count;
340 int sco_cb_count;
341 int acl_cb_count;
342 int iso_cb_count;
343
344 int max_acl_data_packet_length;
345 int max_sco_data_packet_length;
346 int max_acl_data_packets;
347 int max_sco_data_packets;
Myles Watsone1708c82023-01-18 17:07:58 -0800348
349 std::vector<uint16_t> sco_connection_handles;
350 std::vector<uint16_t> acl_connection_handles;
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000351};
352
353// Discard NO-OPs from the event queue.
354void BluetoothAidlTest::handle_no_ops() {
355 while (!event_queue.empty()) {
356 std::vector<uint8_t> event;
357 event_queue.front(event);
358 ASSERT_GE(event.size(),
359 static_cast<size_t>(kEventCommandCompleteStatusByte));
360 bool event_is_no_op =
361 (event[kEventCodeByte] == kEventCommandComplete) &&
362 (event[kEventCommandCompleteOpcodeLsByte] == 0x00) &&
363 (event[kEventCommandCompleteOpcodeLsByte + 1] == 0x00);
364 event_is_no_op |= (event[kEventCodeByte] == kEventCommandStatus) &&
365 (event[kEventCommandStatusOpcodeLsByte] == 0x00) &&
366 (event[kEventCommandStatusOpcodeLsByte + 1] == 0x00);
367 if (event_is_no_op) {
368 event_queue.pop(event);
369 } else {
370 break;
371 }
372 }
Myles Watsone1708c82023-01-18 17:07:58 -0800373}
374
375// Discard Qualcomm ACL debugging
376void BluetoothAidlTest::discard_qca_debugging() {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000377 while (!acl_queue.empty()) {
378 std::vector<uint8_t> acl_packet;
379 acl_queue.front(acl_packet);
380 uint16_t connection_handle = acl_packet[1] & 0xF;
381 connection_handle <<= 8;
382 connection_handle |= acl_packet[0];
383 bool packet_is_no_op = connection_handle == kAclHandleQcaDebugMessage;
384 if (packet_is_no_op) {
385 acl_queue.pop(acl_packet);
386 } else {
387 break;
388 }
389 }
390}
391
392// Receive an event, discarding NO-OPs.
393void BluetoothAidlTest::wait_for_event(bool timeout_is_error = true) {
Myles Watsone1708c82023-01-18 17:07:58 -0800394 // Wait until we get something that's not a no-op.
395 while (true) {
396 bool event_ready = event_queue.waitWithTimeout(kWaitForHciEventTimeout);
397 ASSERT_TRUE(event_ready || !timeout_is_error);
398 if (event_queue.empty()) {
399 // waitWithTimeout timed out
400 return;
401 }
402 handle_no_ops();
403 if (!event_queue.empty()) {
404 // There's an event in the queue that's not a no-op.
405 return;
406 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000407 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000408}
409
410// Wait until a command complete is received.
411void BluetoothAidlTest::wait_for_command_complete_event(
412 std::vector<uint8_t> cmd) {
Myles Watsone1708c82023-01-18 17:07:58 -0800413 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000414 std::vector<uint8_t> event;
Myles Watsone1708c82023-01-18 17:07:58 -0800415 ASSERT_FALSE(event_queue.empty());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000416 ASSERT_TRUE(event_queue.pop(event));
417
418 ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
419 ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
420 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
421 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
422 ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
423}
424
425// Send the command to read the controller's buffer sizes.
426void BluetoothAidlTest::setBufferSizes() {
427 std::vector<uint8_t> cmd{
428 kCommandHciReadBufferSize,
429 kCommandHciReadBufferSize + sizeof(kCommandHciReadBufferSize)};
430 hci->sendHciCommand(cmd);
431
Myles Watsone1708c82023-01-18 17:07:58 -0800432 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000433 if (event_queue.empty()) {
434 return;
435 }
436 std::vector<uint8_t> event;
437 ASSERT_TRUE(event_queue.pop(event));
438
439 ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
440 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
441 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
442 ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
443
444 max_acl_data_packet_length =
445 event[kEventCommandCompleteStatusByte + 1] +
446 (event[kEventCommandCompleteStatusByte + 2] << 8);
447 max_sco_data_packet_length = event[kEventCommandCompleteStatusByte + 3];
448 max_acl_data_packets = event[kEventCommandCompleteStatusByte + 4] +
449 (event[kEventCommandCompleteStatusByte + 5] << 8);
450 max_sco_data_packets = event[kEventCommandCompleteStatusByte + 6] +
451 (event[kEventCommandCompleteStatusByte + 7] << 8);
452
453 ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
454 static_cast<int>(max_acl_data_packet_length),
455 static_cast<int>(max_acl_data_packets),
456 static_cast<int>(max_sco_data_packet_length),
457 static_cast<int>(max_sco_data_packets));
458}
459
Myles Watsone1708c82023-01-18 17:07:58 -0800460// Enable flow control packets for SCO
461void BluetoothAidlTest::setSynchronousFlowControlEnable() {
462 std::vector<uint8_t> cmd{kCommandHciSynchronousFlowControlEnable,
463 kCommandHciSynchronousFlowControlEnable +
464 sizeof(kCommandHciSynchronousFlowControlEnable)};
465 hci->sendHciCommand(cmd);
466
467 wait_for_command_complete_event(cmd);
468}
469
470// Send an HCI command (in Loopback mode) and check the response.
471void BluetoothAidlTest::sendAndCheckHci(int num_packets) {
472 ThroughputLogger logger = {__func__};
473 int command_size = 0;
474 for (int n = 0; n < num_packets; n++) {
475 // Send an HCI packet
476 std::vector<uint8_t> write_name{
477 kCommandHciWriteLocalName,
478 kCommandHciWriteLocalName + sizeof(kCommandHciWriteLocalName)};
479 // With a name
480 char new_name[] = "John Jacob Jingleheimer Schmidt ___________________0";
481 size_t new_name_length = strlen(new_name);
482 for (size_t i = 0; i < new_name_length; i++) {
483 write_name.push_back(static_cast<uint8_t>(new_name[i]));
484 }
485 // And the packet number
486 size_t i = new_name_length - 1;
487 for (int digits = n; digits > 0; digits = digits / 10, i--) {
488 write_name[i] = static_cast<uint8_t>('0' + digits % 10);
489 }
490 // And padding
491 for (size_t i = 0; i < 248 - new_name_length; i++) {
492 write_name.push_back(static_cast<uint8_t>(0));
493 }
494
495 hci->sendHciCommand(write_name);
496
497 // Check the loopback of the HCI packet
498 ASSERT_NO_FATAL_FAILURE(wait_for_event());
499
500 std::vector<uint8_t> event;
501 ASSERT_TRUE(event_queue.pop(event));
502
503 size_t compare_length = (write_name.size() > static_cast<size_t>(0xff)
504 ? static_cast<size_t>(0xff)
505 : write_name.size());
506 ASSERT_GT(event.size(), compare_length + kEventFirstPayloadByte - 1);
507
508 ASSERT_EQ(kEventLoopbackCommand, event[kEventCodeByte]);
509 ASSERT_EQ(compare_length, event[kEventLengthByte]);
510
511 // Don't compare past the end of the event.
512 if (compare_length + kEventFirstPayloadByte > event.size()) {
513 compare_length = event.size() - kEventFirstPayloadByte;
514 ALOGE("Only comparing %d bytes", static_cast<int>(compare_length));
515 }
516
517 if (n == num_packets - 1) {
518 command_size = write_name.size();
519 }
520
521 for (size_t i = 0; i < compare_length; i++) {
522 ASSERT_EQ(write_name[i], event[kEventFirstPayloadByte + i]);
523 }
524 }
525 logger.setTotalBytes(command_size * num_packets * 2);
526}
527
528// Send a SCO data packet (in Loopback mode) and check the response.
529void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size,
530 uint16_t handle) {
531 ThroughputLogger logger = {__func__};
532 for (int n = 0; n < num_packets; n++) {
533 // Send a SCO packet
534 std::vector<uint8_t> sco_packet;
535 sco_packet.push_back(static_cast<uint8_t>(handle & 0xff));
536 sco_packet.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8));
537 sco_packet.push_back(static_cast<uint8_t>(size & 0xff));
538 for (size_t i = 0; i < size; i++) {
539 sco_packet.push_back(static_cast<uint8_t>(i + n));
540 }
541 hci->sendScoData(sco_packet);
542
543 // Check the loopback of the SCO packet
544 std::vector<uint8_t> sco_loopback;
545 ASSERT_TRUE(
546 sco_queue.tryPopWithTimeout(sco_loopback, kWaitForScoDataTimeout));
547
548 ASSERT_EQ(sco_packet.size(), sco_loopback.size());
549 size_t successful_bytes = 0;
550
551 for (size_t i = 0; i < sco_packet.size(); i++) {
552 if (sco_packet[i] == sco_loopback[i]) {
553 successful_bytes = i;
554 } else {
555 ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
556 sco_packet[i], sco_loopback[i]);
557 ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
558 sco_packet[i + 1], sco_loopback[i + 1]);
559 break;
560 }
561 }
562 ASSERT_EQ(sco_packet.size(), successful_bytes + 1);
563 }
564 logger.setTotalBytes(num_packets * size * 2);
565}
566
567// Send an ACL data packet (in Loopback mode) and check the response.
568void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size,
569 uint16_t handle) {
570 ThroughputLogger logger = {__func__};
571 for (int n = 0; n < num_packets; n++) {
572 // Send an ACL packet
573 std::vector<uint8_t> acl_packet;
574 acl_packet.push_back(static_cast<uint8_t>(handle & 0xff));
575 acl_packet.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8) |
576 kAclBroadcastPointToPoint |
577 kAclPacketBoundaryFirstAutoFlushable);
578 acl_packet.push_back(static_cast<uint8_t>(size & 0xff));
579 acl_packet.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
580 for (size_t i = 0; i < size; i++) {
581 acl_packet.push_back(static_cast<uint8_t>(i + n));
582 }
583 hci->sendAclData(acl_packet);
584
585 std::vector<uint8_t> acl_loopback;
586 // Check the loopback of the ACL packet
587 ASSERT_TRUE(
588 acl_queue.tryPopWithTimeout(acl_loopback, kWaitForAclDataTimeout));
589
590 ASSERT_EQ(acl_packet.size(), acl_loopback.size());
591 size_t successful_bytes = 0;
592
593 for (size_t i = 0; i < acl_packet.size(); i++) {
594 if (acl_packet[i] == acl_loopback[i]) {
595 successful_bytes = i;
596 } else {
597 ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
598 acl_packet[i], acl_loopback[i]);
599 ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
600 acl_packet[i + 1], acl_loopback[i + 1]);
601 break;
602 }
603 }
604 ASSERT_EQ(acl_packet.size(), successful_bytes + 1);
605 }
606 logger.setTotalBytes(num_packets * size * 2);
607}
608
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000609// Return the number of completed packets reported by the controller.
610int BluetoothAidlTest::wait_for_completed_packets_event(uint16_t handle) {
611 int packets_processed = 0;
Myles Watson65b47f52023-01-26 12:59:06 -0800612 while (true) {
613 // There should be at least one event.
614 wait_for_event(packets_processed == 0);
615 if (event_queue.empty()) {
616 if (packets_processed == 0) {
617 ALOGW("%s: waitForBluetoothCallback timed out.", __func__);
618 }
619 return packets_processed;
620 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000621 std::vector<uint8_t> event;
622 EXPECT_TRUE(event_queue.pop(event));
623
624 EXPECT_EQ(kEventNumberOfCompletedPackets, event[kEventCodeByte]);
625 EXPECT_EQ(1, event[kEventNumberOfCompletedPacketsNumHandles]);
626
627 uint16_t event_handle = event[3] + (event[4] << 8);
628 EXPECT_EQ(handle, event_handle);
629
630 packets_processed += event[5] + (event[6] << 8);
631 }
632 return packets_processed;
633}
634
Myles Watsone1708c82023-01-18 17:07:58 -0800635// Send local loopback command and initialize SCO and ACL handles.
636void BluetoothAidlTest::enterLoopbackMode() {
637 std::vector<uint8_t> cmd{kCommandHciWriteLoopbackModeLocal,
638 kCommandHciWriteLoopbackModeLocal +
639 sizeof(kCommandHciWriteLoopbackModeLocal)};
640 hci->sendHciCommand(cmd);
641
642 // Receive connection complete events with data channels
643 int connection_event_count = 0;
644 bool command_complete_received = false;
645 while (true) {
646 wait_for_event(false);
647 if (event_queue.empty()) {
648 // Fail if there was no event received or no connections completed.
649 ASSERT_TRUE(command_complete_received);
650 ASSERT_LT(0, connection_event_count);
651 return;
652 }
653 std::vector<uint8_t> event;
654 ASSERT_TRUE(event_queue.pop(event));
655 ASSERT_GT(event.size(),
656 static_cast<size_t>(kEventCommandCompleteStatusByte));
657 if (event[kEventCodeByte] == kEventConnectionComplete) {
658 ASSERT_GT(event.size(),
659 static_cast<size_t>(kEventConnectionCompleteType));
660 ASSERT_EQ(event[kEventLengthByte], kEventConnectionCompleteParamLength);
661 uint8_t connection_type = event[kEventConnectionCompleteType];
662
663 ASSERT_TRUE(connection_type == kEventConnectionCompleteTypeSco ||
664 connection_type == kEventConnectionCompleteTypeAcl);
665
666 // Save handles
667 uint16_t handle = event[kEventConnectionCompleteHandleLsByte] |
668 event[kEventConnectionCompleteHandleLsByte + 1] << 8;
669 if (connection_type == kEventConnectionCompleteTypeSco) {
670 sco_connection_handles.push_back(handle);
671 } else {
672 acl_connection_handles.push_back(handle);
673 }
674
675 ALOGD("Connect complete type = %d handle = %d",
676 event[kEventConnectionCompleteType], handle);
677 connection_event_count++;
678 } else {
679 ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
680 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
681 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
682 ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
683 command_complete_received = true;
684 }
685 }
686}
687
688// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
689TEST_P(BluetoothAidlTest, InitializeAndClose) {}
690
691// Send an HCI Reset with sendHciCommand and wait for a command complete event.
Myles Watson65b47f52023-01-26 12:59:06 -0800692TEST_P(BluetoothAidlTest, HciReset) {
693 std::vector<uint8_t> reset{kCommandHciReset,
694 kCommandHciReset + sizeof(kCommandHciReset)};
695 hci->sendHciCommand(reset);
696
697 wait_for_command_complete_event(reset);
698}
Myles Watsone1708c82023-01-18 17:07:58 -0800699
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000700// Read and check the HCI version of the controller.
701TEST_P(BluetoothAidlTest, HciVersionTest) {
702 std::vector<uint8_t> cmd{kCommandHciReadLocalVersionInformation,
703 kCommandHciReadLocalVersionInformation +
704 sizeof(kCommandHciReadLocalVersionInformation)};
705 hci->sendHciCommand(cmd);
706
Myles Watsone1708c82023-01-18 17:07:58 -0800707 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000708
709 std::vector<uint8_t> event;
710 ASSERT_TRUE(event_queue.pop(event));
711 ASSERT_GT(event.size(), static_cast<size_t>(kEventLocalLmpVersionByte));
712
713 ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
714 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
715 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
716 ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
717
718 ASSERT_LE(kHciMinimumHciVersion, event[kEventLocalHciVersionByte]);
719 ASSERT_LE(kHciMinimumLmpVersion, event[kEventLocalLmpVersionByte]);
720}
721
722// Send an unknown HCI command and wait for the error message.
723TEST_P(BluetoothAidlTest, HciUnknownCommand) {
724 std::vector<uint8_t> cmd{
725 kCommandHciShouldBeUnknown,
726 kCommandHciShouldBeUnknown + sizeof(kCommandHciShouldBeUnknown)};
727 hci->sendHciCommand(cmd);
728
Myles Watsone1708c82023-01-18 17:07:58 -0800729 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000730
731 std::vector<uint8_t> event;
732 ASSERT_TRUE(event_queue.pop(event));
733
734 ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
735 if (event[kEventCodeByte] == kEventCommandComplete) {
736 ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
737 ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
738 ASSERT_EQ(kHciStatusUnknownHciCommand,
739 event[kEventCommandCompleteStatusByte]);
740 } else {
741 ASSERT_EQ(kEventCommandStatus, event[kEventCodeByte]);
742 ASSERT_EQ(cmd[0], event[kEventCommandStatusOpcodeLsByte]);
743 ASSERT_EQ(cmd[1], event[kEventCommandStatusOpcodeLsByte + 1]);
744 ASSERT_EQ(kHciStatusUnknownHciCommand,
745 event[kEventCommandStatusStatusByte]);
746 }
747}
748
Myles Watsone1708c82023-01-18 17:07:58 -0800749// Enter loopback mode, but don't send any packets.
Myles Watson65b47f52023-01-26 12:59:06 -0800750TEST_P(BluetoothAidlTest, WriteLoopbackMode) { enterLoopbackMode(); }
Myles Watsone1708c82023-01-18 17:07:58 -0800751
752// Enter loopback mode and send a single command.
753TEST_P(BluetoothAidlTest, LoopbackModeSingleCommand) {
Myles Watsone1708c82023-01-18 17:07:58 -0800754 setBufferSizes();
755
756 enterLoopbackMode();
757
758 sendAndCheckHci(1);
759}
760
761// Enter loopback mode and send a single SCO packet.
762TEST_P(BluetoothAidlTest, LoopbackModeSingleSco) {
Myles Watsone1708c82023-01-18 17:07:58 -0800763 setBufferSizes();
764 setSynchronousFlowControlEnable();
765
766 enterLoopbackMode();
767
768 if (!sco_connection_handles.empty()) {
769 ASSERT_LT(0, max_sco_data_packet_length);
770 sendAndCheckSco(1, max_sco_data_packet_length, sco_connection_handles[0]);
771 int sco_packets_sent = 1;
772 int completed_packets =
773 wait_for_completed_packets_event(sco_connection_handles[0]);
774 if (sco_packets_sent != completed_packets) {
775 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
776 sco_packets_sent, completed_packets);
777 }
778 }
779}
780
781// Enter loopback mode and send a single ACL packet.
782TEST_P(BluetoothAidlTest, LoopbackModeSingleAcl) {
Myles Watsone1708c82023-01-18 17:07:58 -0800783 setBufferSizes();
784
785 enterLoopbackMode();
786
787 if (!acl_connection_handles.empty()) {
788 ASSERT_LT(0, max_acl_data_packet_length);
789 sendAndCheckAcl(1, max_acl_data_packet_length - 1,
790 acl_connection_handles[0]);
791 int acl_packets_sent = 1;
792 int completed_packets =
793 wait_for_completed_packets_event(acl_connection_handles[0]);
794 if (acl_packets_sent != completed_packets) {
795 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
796 acl_packets_sent, completed_packets);
797 }
798 }
799 ASSERT_GE(acl_cb_count, 1);
800}
801
802// Enter loopback mode and send command packets for bandwidth measurements.
803TEST_P(BluetoothAidlTest, LoopbackModeCommandBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800804 setBufferSizes();
805
806 enterLoopbackMode();
807
808 sendAndCheckHci(kNumHciCommandsBandwidth);
809}
810
811// Enter loopback mode and send SCO packets for bandwidth measurements.
812TEST_P(BluetoothAidlTest, LoopbackModeScoBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800813 setBufferSizes();
814 setSynchronousFlowControlEnable();
815
816 enterLoopbackMode();
817
818 if (!sco_connection_handles.empty()) {
819 ASSERT_LT(0, max_sco_data_packet_length);
820 sendAndCheckSco(kNumScoPacketsBandwidth, max_sco_data_packet_length,
821 sco_connection_handles[0]);
822 int sco_packets_sent = kNumScoPacketsBandwidth;
823 int completed_packets =
824 wait_for_completed_packets_event(sco_connection_handles[0]);
825 if (sco_packets_sent != completed_packets) {
826 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
827 sco_packets_sent, completed_packets);
828 }
829 }
830}
831
832// Enter loopback mode and send packets for ACL bandwidth measurements.
833TEST_P(BluetoothAidlTest, LoopbackModeAclBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800834 setBufferSizes();
835
836 enterLoopbackMode();
837
838 if (!acl_connection_handles.empty()) {
839 ASSERT_LT(0, max_acl_data_packet_length);
840 sendAndCheckAcl(kNumAclPacketsBandwidth, max_acl_data_packet_length - 1,
841 acl_connection_handles[0]);
842 int acl_packets_sent = kNumAclPacketsBandwidth;
843 int completed_packets =
844 wait_for_completed_packets_event(acl_connection_handles[0]);
845 if (acl_packets_sent != completed_packets) {
846 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
847 acl_packets_sent, completed_packets);
848 }
849 }
850}
851
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000852// Set all bits in the event mask
853TEST_P(BluetoothAidlTest, SetEventMask) {
854 std::vector<uint8_t> set_event_mask{
855 0x01, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
856 0xff, 0xff};
857 hci->sendHciCommand({set_event_mask});
858 wait_for_command_complete_event(set_event_mask);
859}
860
861// Set all bits in the LE event mask
862TEST_P(BluetoothAidlTest, SetLeEventMask) {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000863 std::vector<uint8_t> set_event_mask{
864 0x20, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
865 0xff, 0xff};
866 hci->sendHciCommand({set_event_mask});
867 wait_for_command_complete_event(set_event_mask);
868}
869
870GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
871INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
872 testing::ValuesIn(android::getAidlHalInstanceNames(
873 IBluetoothHci::descriptor)),
874 android::PrintInstanceNameToString);
875
876int main(int argc, char** argv) {
877 ABinderProcess_startThreadPool();
878 ::testing::InitGoogleTest(&argc, argv);
879 int status = RUN_ALL_TESTS();
880 ALOGI("Test result = %d", status);
881 return status;
882}