blob: 43cb914d801b2718066d8b65399b03f0e3cd9c79 [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
Myles Watson51b8bae2023-01-27 14:22:24 -080038// TODO: Remove custom logging defines from PDL packets.
39#undef LOG_INFO
40#undef LOG_DEBUG
41#undef LOG_TAG
42#define LOG_TAG "VtsHalBluetooth"
43#include "hci/hci_packets.h"
44#include "packet/raw_builder.h"
45
Dylan Tian8a6e09c2022-08-16 07:29:28 +000046using aidl::android::hardware::bluetooth::IBluetoothHci;
47using aidl::android::hardware::bluetooth::IBluetoothHciCallbacks;
48using aidl::android::hardware::bluetooth::Status;
49using ndk::ScopedAStatus;
50using ndk::SpAIBinder;
51
Myles Watsone1708c82023-01-18 17:07:58 -080052static constexpr size_t kNumHciCommandsBandwidth = 100;
53static constexpr size_t kNumScoPacketsBandwidth = 100;
54static constexpr size_t kNumAclPacketsBandwidth = 100;
Dylan Tian8a6e09c2022-08-16 07:29:28 +000055static constexpr std::chrono::milliseconds kWaitForInitTimeout(2000);
56static constexpr std::chrono::milliseconds kWaitForHciEventTimeout(2000);
Myles Watsone1708c82023-01-18 17:07:58 -080057static constexpr std::chrono::milliseconds kWaitForScoDataTimeout(1000);
58static constexpr std::chrono::milliseconds kWaitForAclDataTimeout(1000);
Dylan Tian8a6e09c2022-08-16 07:29:28 +000059static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200);
60
Dylan Tian8a6e09c2022-08-16 07:29:28 +000061// To discard Qualcomm ACL debugging
62static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
63
64class ThroughputLogger {
65 public:
66 ThroughputLogger(std::string task)
Myles Watsone1708c82023-01-18 17:07:58 -080067 : total_bytes_(0),
68 task_(task),
69 start_time_(std::chrono::steady_clock::now()) {}
Dylan Tian8a6e09c2022-08-16 07:29:28 +000070
71 ~ThroughputLogger() {
72 if (total_bytes_ == 0) {
73 return;
74 }
75 std::chrono::duration<double> duration =
76 std::chrono::steady_clock::now() - start_time_;
77 double s = duration.count();
78 if (s == 0) {
79 return;
80 }
81 double rate_kb = (static_cast<double>(total_bytes_) / s) / 1024;
82 ALOGD("%s %.1f KB/s (%zu bytes in %.3fs)", task_.c_str(), rate_kb,
83 total_bytes_, s);
84 }
85
86 void setTotalBytes(size_t total_bytes) { total_bytes_ = total_bytes; }
87
88 private:
89 size_t total_bytes_;
90 std::string task_;
91 std::chrono::steady_clock::time_point start_time_;
92};
93
94// The main test class for Bluetooth HAL.
95class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
96 public:
97 virtual void SetUp() override {
98 // currently test passthrough mode only
99 hci = IBluetoothHci::fromBinder(
100 SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
101 ASSERT_NE(hci, nullptr);
102 ALOGI("%s: getService() for bluetooth hci is %s", __func__,
103 hci->isRemote() ? "remote" : "local");
104
105 // Lambda function
106 auto on_binder_death = [](void* /*cookie*/) { FAIL(); };
107
108 bluetooth_hci_death_recipient =
109 AIBinder_DeathRecipient_new(on_binder_death);
110 ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
111 ASSERT_EQ(STATUS_OK,
112 AIBinder_linkToDeath(hci->asBinder().get(),
113 bluetooth_hci_death_recipient, 0));
114
115 hci_cb = ndk::SharedRefBase::make<BluetoothHciCallbacks>(*this);
116 ASSERT_NE(hci_cb, nullptr);
117
118 max_acl_data_packet_length = 0;
119 max_sco_data_packet_length = 0;
120 max_acl_data_packets = 0;
121 max_sco_data_packets = 0;
122
123 event_cb_count = 0;
124 acl_cb_count = 0;
125 sco_cb_count = 0;
126
127 ASSERT_TRUE(hci->initialize(hci_cb).isOk());
128 auto future = initialized_promise.get_future();
129 auto timeout_status = future.wait_for(kWaitForInitTimeout);
130 ASSERT_EQ(timeout_status, std::future_status::ready);
131 ASSERT_TRUE(future.get());
132 }
133
134 virtual void TearDown() override {
135 ALOGI("TearDown");
136 // Should not be checked in production code
137 ASSERT_TRUE(hci->close().isOk());
138 std::this_thread::sleep_for(kInterfaceCloseDelayMs);
139 handle_no_ops();
Myles Watsone1708c82023-01-18 17:07:58 -0800140 discard_qca_debugging();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000141 EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
142 EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
143 EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
144 EXPECT_EQ(static_cast<size_t>(0), iso_queue.size());
145 }
146
147 void setBufferSizes();
Myles Watsone1708c82023-01-18 17:07:58 -0800148 void setSynchronousFlowControlEnable();
149
150 // Functions called from within tests in loopback mode
151 void sendAndCheckHci(int num_packets);
152 void sendAndCheckSco(int num_packets, size_t size, uint16_t handle);
153 void sendAndCheckAcl(int num_packets, size_t size, uint16_t handle);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000154
155 // Helper functions to try to get a handle on verbosity
Myles Watsone1708c82023-01-18 17:07:58 -0800156 void enterLoopbackMode();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000157 void handle_no_ops();
Myles Watsone1708c82023-01-18 17:07:58 -0800158 void discard_qca_debugging();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000159 void wait_for_event(bool timeout_is_error);
Myles Watson51b8bae2023-01-27 14:22:24 -0800160 void wait_for_command_complete_event(::bluetooth::hci::OpCode opCode);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000161 int wait_for_completed_packets_event(uint16_t handle);
162
163 // A simple test implementation of BluetoothHciCallbacks.
164 class BluetoothHciCallbacks
165 : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
166 BluetoothAidlTest& parent_;
167
168 public:
169 BluetoothHciCallbacks(BluetoothAidlTest& parent) : parent_(parent){};
170
171 virtual ~BluetoothHciCallbacks() = default;
172
173 ndk::ScopedAStatus initializationComplete(Status status) {
174 parent_.initialized_promise.set_value(status == Status::SUCCESS);
175 ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
176 return ScopedAStatus::ok();
177 };
178
179 ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& event) {
180 parent_.event_cb_count++;
181 parent_.event_queue.push(event);
182 ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
183 return ScopedAStatus::ok();
184 };
185
186 ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& data) {
187 parent_.acl_cb_count++;
188 parent_.acl_queue.push(data);
189 return ScopedAStatus::ok();
190 };
191
192 ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& data) {
193 parent_.sco_cb_count++;
194 parent_.sco_queue.push(data);
195 return ScopedAStatus::ok();
196 };
197
198 ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& data) {
199 parent_.iso_cb_count++;
200 parent_.iso_queue.push(data);
201 return ScopedAStatus::ok();
202 };
203 };
204
205 template <class T>
206 class WaitQueue {
207 public:
208 WaitQueue(){};
209
210 virtual ~WaitQueue() = default;
211
212 bool empty() const {
213 std::lock_guard<std::mutex> lock(m_);
214 return q_.empty();
215 };
216
217 size_t size() const {
218 std::lock_guard<std::mutex> lock(m_);
219 return q_.size();
220 };
221
222 void push(const T& v) {
223 std::lock_guard<std::mutex> lock(m_);
224 q_.push(v);
225 ready_.notify_one();
226 };
227
228 bool pop(T& v) {
229 std::lock_guard<std::mutex> lock(m_);
230 if (q_.empty()) {
231 return false;
232 }
233 v = std::move(q_.front());
234 q_.pop();
235 return true;
236 };
237
Myles Watson51b8bae2023-01-27 14:22:24 -0800238 void pop() {
239 std::lock_guard<std::mutex> lock(m_);
240 if (q_.empty()) {
241 return;
242 }
243 q_.pop();
244 };
245
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000246 bool front(T& v) {
247 std::lock_guard<std::mutex> lock(m_);
248 if (q_.empty()) {
249 return false;
250 }
251 v = q_.front();
252 return true;
253 };
254
255 void wait() {
256 std::unique_lock<std::mutex> lock(m_);
257 while (q_.empty()) {
258 ready_.wait(lock);
259 }
260 };
261
262 bool waitWithTimeout(std::chrono::milliseconds timeout) {
263 std::unique_lock<std::mutex> lock(m_);
264 while (q_.empty()) {
265 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
266 return false;
267 }
268 }
269 return true;
270 };
271
272 bool tryPopWithTimeout(T& v, std::chrono::milliseconds timeout) {
273 std::unique_lock<std::mutex> lock(m_);
274 while (q_.empty()) {
275 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
276 return false;
277 }
278 }
279 v = std::move(q_.front());
280 q_.pop();
281 return true;
282 };
283
284 private:
285 mutable std::mutex m_;
286 std::queue<T> q_;
287 std::condition_variable_any ready_;
288 };
289
290 std::shared_ptr<IBluetoothHci> hci;
291 std::shared_ptr<BluetoothHciCallbacks> hci_cb;
292 AIBinder_DeathRecipient* bluetooth_hci_death_recipient;
293 WaitQueue<std::vector<uint8_t>> event_queue;
294 WaitQueue<std::vector<uint8_t>> acl_queue;
295 WaitQueue<std::vector<uint8_t>> sco_queue;
296 WaitQueue<std::vector<uint8_t>> iso_queue;
297
298 std::promise<bool> initialized_promise;
299 int event_cb_count;
300 int sco_cb_count;
301 int acl_cb_count;
302 int iso_cb_count;
303
304 int max_acl_data_packet_length;
305 int max_sco_data_packet_length;
306 int max_acl_data_packets;
307 int max_sco_data_packets;
Myles Watsone1708c82023-01-18 17:07:58 -0800308
309 std::vector<uint16_t> sco_connection_handles;
310 std::vector<uint16_t> acl_connection_handles;
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000311};
312
313// Discard NO-OPs from the event queue.
314void BluetoothAidlTest::handle_no_ops() {
315 while (!event_queue.empty()) {
316 std::vector<uint8_t> event;
317 event_queue.front(event);
Myles Watson51b8bae2023-01-27 14:22:24 -0800318 auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
319 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
320 std::make_shared<std::vector<uint8_t>>(event))));
321 auto status_view = ::bluetooth::hci::CommandCompleteView::Create(
322 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
323 std::make_shared<std::vector<uint8_t>>(event))));
324 bool is_complete_no_op =
325 complete_view.IsValid() &&
326 complete_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
327 bool is_status_no_op =
328 status_view.IsValid() &&
329 status_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
330 if (is_complete_no_op || is_status_no_op) {
331 event_queue.pop();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000332 } else {
333 break;
334 }
335 }
Myles Watsone1708c82023-01-18 17:07:58 -0800336}
337
338// Discard Qualcomm ACL debugging
339void BluetoothAidlTest::discard_qca_debugging() {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000340 while (!acl_queue.empty()) {
341 std::vector<uint8_t> acl_packet;
342 acl_queue.front(acl_packet);
Myles Watson51b8bae2023-01-27 14:22:24 -0800343 auto acl_view =
344 ::bluetooth::hci::AclView::Create(::bluetooth::hci::PacketView<true>(
345 std::make_shared<std::vector<uint8_t>>(acl_packet)));
346 EXPECT_TRUE(acl_view.IsValid());
347 if (acl_view.GetHandle() == kAclHandleQcaDebugMessage) {
348 acl_queue.pop();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000349 } else {
350 break;
351 }
352 }
353}
354
355// Receive an event, discarding NO-OPs.
356void BluetoothAidlTest::wait_for_event(bool timeout_is_error = true) {
Myles Watsone1708c82023-01-18 17:07:58 -0800357 // Wait until we get something that's not a no-op.
358 while (true) {
359 bool event_ready = event_queue.waitWithTimeout(kWaitForHciEventTimeout);
360 ASSERT_TRUE(event_ready || !timeout_is_error);
361 if (event_queue.empty()) {
362 // waitWithTimeout timed out
363 return;
364 }
365 handle_no_ops();
366 if (!event_queue.empty()) {
367 // There's an event in the queue that's not a no-op.
368 return;
369 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000370 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000371}
372
373// Wait until a command complete is received.
374void BluetoothAidlTest::wait_for_command_complete_event(
Myles Watson51b8bae2023-01-27 14:22:24 -0800375 ::bluetooth::hci::OpCode opCode) {
Myles Watsone1708c82023-01-18 17:07:58 -0800376 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000377 std::vector<uint8_t> event;
Myles Watsone1708c82023-01-18 17:07:58 -0800378 ASSERT_FALSE(event_queue.empty());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000379 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800380 auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
381 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
382 std::make_shared<std::vector<uint8_t>>(event))));
383 ASSERT_TRUE(complete_view.IsValid());
384 ASSERT_EQ(complete_view.GetCommandOpCode(), opCode);
385 ASSERT_EQ(complete_view.GetPayload()[0],
386 static_cast<uint8_t>(::bluetooth::hci::ErrorCode::SUCCESS));
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000387}
388
389// Send the command to read the controller's buffer sizes.
390void BluetoothAidlTest::setBufferSizes() {
Myles Watson51b8bae2023-01-27 14:22:24 -0800391 std::vector<uint8_t> cmd;
392 ::bluetooth::packet::BitInserter bi{cmd};
393 ::bluetooth::hci::ReadBufferSizeBuilder::Create()->Serialize(bi);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000394 hci->sendHciCommand(cmd);
395
Myles Watsone1708c82023-01-18 17:07:58 -0800396 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000397 std::vector<uint8_t> event;
398 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800399 auto complete_view = ::bluetooth::hci::ReadBufferSizeCompleteView::Create(
400 ::bluetooth::hci::CommandCompleteView::Create(
401 ::bluetooth::hci::EventView::Create(
402 ::bluetooth::hci::PacketView<true>(
403 std::make_shared<std::vector<uint8_t>>(event)))));
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000404
Myles Watson51b8bae2023-01-27 14:22:24 -0800405 ASSERT_TRUE(complete_view.IsValid());
406 ASSERT_EQ(complete_view.GetStatus(), ::bluetooth::hci::ErrorCode::SUCCESS);
407 max_acl_data_packet_length = complete_view.GetAclDataPacketLength();
408 max_sco_data_packet_length = complete_view.GetSynchronousDataPacketLength();
409 max_acl_data_packets = complete_view.GetTotalNumAclDataPackets();
410 max_sco_data_packets = complete_view.GetTotalNumSynchronousDataPackets();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000411
412 ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
413 static_cast<int>(max_acl_data_packet_length),
414 static_cast<int>(max_acl_data_packets),
415 static_cast<int>(max_sco_data_packet_length),
416 static_cast<int>(max_sco_data_packets));
417}
418
Myles Watsone1708c82023-01-18 17:07:58 -0800419// Enable flow control packets for SCO
420void BluetoothAidlTest::setSynchronousFlowControlEnable() {
Myles Watson51b8bae2023-01-27 14:22:24 -0800421 std::vector<uint8_t> cmd;
422 ::bluetooth::packet::BitInserter bi{cmd};
423 ::bluetooth::hci::WriteSynchronousFlowControlEnableBuilder::Create(
424 ::bluetooth::hci::Enable::ENABLED)
425 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800426 hci->sendHciCommand(cmd);
427
Myles Watson51b8bae2023-01-27 14:22:24 -0800428 wait_for_command_complete_event(
429 ::bluetooth::hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE);
Myles Watsone1708c82023-01-18 17:07:58 -0800430}
431
432// Send an HCI command (in Loopback mode) and check the response.
433void BluetoothAidlTest::sendAndCheckHci(int num_packets) {
434 ThroughputLogger logger = {__func__};
435 int command_size = 0;
Myles Watson51b8bae2023-01-27 14:22:24 -0800436 char new_name[] = "John Jacob Jingleheimer Schmidt ___________________";
437 size_t new_name_length = strlen(new_name);
Myles Watsone1708c82023-01-18 17:07:58 -0800438 for (int n = 0; n < num_packets; n++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800439 // The name to set is new_name
440 std::array<uint8_t, 248> name_array;
Myles Watsone1708c82023-01-18 17:07:58 -0800441 for (size_t i = 0; i < new_name_length; i++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800442 name_array[i] = new_name[i];
Myles Watsone1708c82023-01-18 17:07:58 -0800443 }
444 // And the packet number
Myles Watson51b8bae2023-01-27 14:22:24 -0800445 char number[11] = "0000000000";
446 snprintf(number, sizeof(number), "%010d", static_cast<int>(n));
447 for (size_t i = new_name_length; i < new_name_length + sizeof(number) - 1;
448 i++) {
449 name_array[new_name_length + i] = number[i];
Myles Watsone1708c82023-01-18 17:07:58 -0800450 }
Myles Watson51b8bae2023-01-27 14:22:24 -0800451 std::vector<uint8_t> write_name;
452 ::bluetooth::packet::BitInserter bi{write_name};
453 ::bluetooth::hci::WriteLocalNameBuilder::Create(name_array)->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800454 hci->sendHciCommand(write_name);
455
456 // Check the loopback of the HCI packet
457 ASSERT_NO_FATAL_FAILURE(wait_for_event());
458
459 std::vector<uint8_t> event;
460 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800461 auto event_view = ::bluetooth::hci::LoopbackCommandView::Create(
462 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
463 std::make_shared<std::vector<uint8_t>>(event))));
464 ASSERT_TRUE(event_view.IsValid());
465 std::vector<uint8_t> looped_back_command{event_view.GetPayload().begin(),
466 event_view.GetPayload().end()};
467 ASSERT_EQ(looped_back_command, write_name);
Myles Watsone1708c82023-01-18 17:07:58 -0800468
469 if (n == num_packets - 1) {
470 command_size = write_name.size();
471 }
Myles Watsone1708c82023-01-18 17:07:58 -0800472 }
473 logger.setTotalBytes(command_size * num_packets * 2);
474}
475
476// Send a SCO data packet (in Loopback mode) and check the response.
477void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size,
478 uint16_t handle) {
479 ThroughputLogger logger = {__func__};
480 for (int n = 0; n < num_packets; n++) {
481 // Send a SCO packet
482 std::vector<uint8_t> sco_packet;
Myles Watson51b8bae2023-01-27 14:22:24 -0800483 std::vector<uint8_t> payload;
Myles Watsone1708c82023-01-18 17:07:58 -0800484 for (size_t i = 0; i < size; i++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800485 payload.push_back(static_cast<uint8_t>(i + n));
Myles Watsone1708c82023-01-18 17:07:58 -0800486 }
Myles Watson51b8bae2023-01-27 14:22:24 -0800487 ::bluetooth::packet::BitInserter bi{sco_packet};
488 ::bluetooth::hci::ScoBuilder::Create(
489 handle, ::bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED, payload)
490 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800491 hci->sendScoData(sco_packet);
492
493 // Check the loopback of the SCO packet
494 std::vector<uint8_t> sco_loopback;
495 ASSERT_TRUE(
496 sco_queue.tryPopWithTimeout(sco_loopback, kWaitForScoDataTimeout));
497
Myles Watson51b8bae2023-01-27 14:22:24 -0800498 ASSERT_EQ(sco_packet, sco_loopback);
Myles Watsone1708c82023-01-18 17:07:58 -0800499 }
500 logger.setTotalBytes(num_packets * size * 2);
501}
502
503// Send an ACL data packet (in Loopback mode) and check the response.
504void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size,
505 uint16_t handle) {
506 ThroughputLogger logger = {__func__};
507 for (int n = 0; n < num_packets; n++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800508 // Send an ACL packet with counting data
509 auto payload = std::make_unique<::bluetooth::packet::RawBuilder>();
Myles Watsone1708c82023-01-18 17:07:58 -0800510 for (size_t i = 0; i < size; i++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800511 payload->AddOctets1(static_cast<uint8_t>(i + n));
Myles Watsone1708c82023-01-18 17:07:58 -0800512 }
Myles Watson51b8bae2023-01-27 14:22:24 -0800513 std::vector<uint8_t> acl_packet;
514 ::bluetooth::packet::BitInserter bi{acl_packet};
515 ::bluetooth::hci::AclBuilder::Create(
516 handle,
517 ::bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE,
518 ::bluetooth::hci::BroadcastFlag::POINT_TO_POINT, std::move(payload))
519 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800520 hci->sendAclData(acl_packet);
521
522 std::vector<uint8_t> acl_loopback;
523 // Check the loopback of the ACL packet
524 ASSERT_TRUE(
525 acl_queue.tryPopWithTimeout(acl_loopback, kWaitForAclDataTimeout));
526
Myles Watson51b8bae2023-01-27 14:22:24 -0800527 ASSERT_EQ(acl_packet, acl_loopback);
Myles Watsone1708c82023-01-18 17:07:58 -0800528 }
529 logger.setTotalBytes(num_packets * size * 2);
530}
531
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000532// Return the number of completed packets reported by the controller.
533int BluetoothAidlTest::wait_for_completed_packets_event(uint16_t handle) {
534 int packets_processed = 0;
Myles Watson65b47f52023-01-26 12:59:06 -0800535 while (true) {
536 // There should be at least one event.
537 wait_for_event(packets_processed == 0);
538 if (event_queue.empty()) {
539 if (packets_processed == 0) {
540 ALOGW("%s: waitForBluetoothCallback timed out.", __func__);
541 }
542 return packets_processed;
543 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000544 std::vector<uint8_t> event;
545 EXPECT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800546 auto event_view = ::bluetooth::hci::NumberOfCompletedPacketsView::Create(
547 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
548 std::make_shared<std::vector<uint8_t>>(event))));
549 if (!event_view.IsValid()) {
550 ADD_FAILURE();
551 return packets_processed;
552 }
553 auto completed_packets = event_view.GetCompletedPackets();
554 for (const auto entry : completed_packets) {
555 EXPECT_EQ(handle, entry.connection_handle_);
556 packets_processed += entry.host_num_of_completed_packets_;
557 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000558 }
559 return packets_processed;
560}
561
Myles Watsone1708c82023-01-18 17:07:58 -0800562// Send local loopback command and initialize SCO and ACL handles.
563void BluetoothAidlTest::enterLoopbackMode() {
Myles Watson51b8bae2023-01-27 14:22:24 -0800564 std::vector<uint8_t> cmd;
565 ::bluetooth::packet::BitInserter bi{cmd};
566 ::bluetooth::hci::WriteLoopbackModeBuilder::Create(
567 bluetooth::hci::LoopbackMode::ENABLE_LOCAL)
568 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800569 hci->sendHciCommand(cmd);
570
571 // Receive connection complete events with data channels
572 int connection_event_count = 0;
573 bool command_complete_received = false;
574 while (true) {
575 wait_for_event(false);
576 if (event_queue.empty()) {
577 // Fail if there was no event received or no connections completed.
578 ASSERT_TRUE(command_complete_received);
579 ASSERT_LT(0, connection_event_count);
580 return;
581 }
582 std::vector<uint8_t> event;
583 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800584 auto event_view =
585 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
586 std::make_shared<std::vector<uint8_t>>(event)));
587 ASSERT_TRUE(event_view.IsValid());
Myles Watsone1708c82023-01-18 17:07:58 -0800588
Myles Watson51b8bae2023-01-27 14:22:24 -0800589 if (event_view.GetEventCode() ==
590 ::bluetooth::hci::EventCode::CONNECTION_COMPLETE) {
591 auto complete_view =
592 ::bluetooth::hci::ConnectionCompleteView::Create(event_view);
593 ASSERT_TRUE(complete_view.IsValid());
594 switch (complete_view.GetLinkType()) {
595 case ::bluetooth::hci::LinkType::ACL:
596 acl_connection_handles.push_back(complete_view.GetConnectionHandle());
597 break;
598 case ::bluetooth::hci::LinkType::SCO:
599 sco_connection_handles.push_back(complete_view.GetConnectionHandle());
600 break;
601 default:
602 ASSERT_EQ(complete_view.GetLinkType(),
603 ::bluetooth::hci::LinkType::ACL);
Myles Watsone1708c82023-01-18 17:07:58 -0800604 }
Myles Watsone1708c82023-01-18 17:07:58 -0800605 connection_event_count++;
606 } else {
Myles Watson51b8bae2023-01-27 14:22:24 -0800607 auto command_complete_view =
608 ::bluetooth::hci::WriteLoopbackModeCompleteView::Create(
609 ::bluetooth::hci::CommandCompleteView::Create(event_view));
610 ASSERT_TRUE(command_complete_view.IsValid());
611 ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
612 command_complete_view.GetStatus());
Myles Watsone1708c82023-01-18 17:07:58 -0800613 command_complete_received = true;
614 }
615 }
616}
617
618// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
619TEST_P(BluetoothAidlTest, InitializeAndClose) {}
620
621// Send an HCI Reset with sendHciCommand and wait for a command complete event.
Myles Watson65b47f52023-01-26 12:59:06 -0800622TEST_P(BluetoothAidlTest, HciReset) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800623 std::vector<uint8_t> reset;
624 ::bluetooth::packet::BitInserter bi{reset};
625 ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi);
Myles Watson65b47f52023-01-26 12:59:06 -0800626 hci->sendHciCommand(reset);
627
Myles Watson51b8bae2023-01-27 14:22:24 -0800628 wait_for_command_complete_event(::bluetooth::hci::OpCode::RESET);
Myles Watson65b47f52023-01-26 12:59:06 -0800629}
Myles Watsone1708c82023-01-18 17:07:58 -0800630
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000631// Read and check the HCI version of the controller.
632TEST_P(BluetoothAidlTest, HciVersionTest) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800633 std::vector<uint8_t> cmd;
634 ::bluetooth::packet::BitInserter bi{cmd};
635 ::bluetooth::hci::ReadLocalVersionInformationBuilder::Create()->Serialize(bi);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000636 hci->sendHciCommand(cmd);
637
Myles Watsone1708c82023-01-18 17:07:58 -0800638 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000639
640 std::vector<uint8_t> event;
641 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800642 auto complete_view =
643 ::bluetooth::hci::ReadLocalVersionInformationCompleteView::Create(
644 ::bluetooth::hci::CommandCompleteView::Create(
645 ::bluetooth::hci::EventView::Create(
646 ::bluetooth::hci::PacketView<true>(
647 std::make_shared<std::vector<uint8_t>>(event)))));
648 ASSERT_TRUE(complete_view.IsValid());
649 ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, complete_view.GetStatus());
650 auto version = complete_view.GetLocalVersionInformation();
651 ASSERT_LE(::bluetooth::hci::HciVersion::V_3_0, version.hci_version_);
652 ASSERT_LE(::bluetooth::hci::LmpVersion::V_3_0, version.lmp_version_);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000653}
654
655// Send an unknown HCI command and wait for the error message.
656TEST_P(BluetoothAidlTest, HciUnknownCommand) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800657 std::vector<uint8_t> cmd;
658 ::bluetooth::packet::BitInserter bi{cmd};
659 ::bluetooth::hci::CommandBuilder::Create(
660 static_cast<::bluetooth::hci::OpCode>(0x3cff),
661 std::make_unique<::bluetooth::packet::RawBuilder>())
662 ->Serialize(bi);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000663 hci->sendHciCommand(cmd);
664
Myles Watsone1708c82023-01-18 17:07:58 -0800665 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000666
667 std::vector<uint8_t> event;
668 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800669 auto event_view =
670 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
671 std::make_shared<std::vector<uint8_t>>(event)));
672 ASSERT_TRUE(event_view.IsValid());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000673
Myles Watson51b8bae2023-01-27 14:22:24 -0800674 switch (event_view.GetEventCode()) {
675 case ::bluetooth::hci::EventCode::COMMAND_COMPLETE: {
676 auto command_complete =
677 ::bluetooth::hci::CommandCompleteView::Create(event_view);
678 ASSERT_TRUE(command_complete.IsValid());
679 ASSERT_EQ(command_complete.GetPayload()[0],
680 static_cast<uint8_t>(
681 ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
682 } break;
683 case ::bluetooth::hci::EventCode::COMMAND_STATUS: {
684 auto command_status =
685 ::bluetooth::hci::CommandStatusView::Create(event_view);
686 ASSERT_TRUE(command_status.IsValid());
687 ASSERT_EQ(command_status.GetStatus(),
688 ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
689 } break;
690 default:
691 ADD_FAILURE();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000692 }
693}
694
Myles Watsone1708c82023-01-18 17:07:58 -0800695// Enter loopback mode, but don't send any packets.
Myles Watson65b47f52023-01-26 12:59:06 -0800696TEST_P(BluetoothAidlTest, WriteLoopbackMode) { enterLoopbackMode(); }
Myles Watsone1708c82023-01-18 17:07:58 -0800697
698// Enter loopback mode and send a single command.
699TEST_P(BluetoothAidlTest, LoopbackModeSingleCommand) {
Myles Watsone1708c82023-01-18 17:07:58 -0800700 setBufferSizes();
701
702 enterLoopbackMode();
703
704 sendAndCheckHci(1);
705}
706
707// Enter loopback mode and send a single SCO packet.
708TEST_P(BluetoothAidlTest, LoopbackModeSingleSco) {
Myles Watsone1708c82023-01-18 17:07:58 -0800709 setBufferSizes();
710 setSynchronousFlowControlEnable();
711
712 enterLoopbackMode();
713
714 if (!sco_connection_handles.empty()) {
715 ASSERT_LT(0, max_sco_data_packet_length);
716 sendAndCheckSco(1, max_sco_data_packet_length, sco_connection_handles[0]);
717 int sco_packets_sent = 1;
718 int completed_packets =
719 wait_for_completed_packets_event(sco_connection_handles[0]);
720 if (sco_packets_sent != completed_packets) {
721 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
722 sco_packets_sent, completed_packets);
723 }
724 }
725}
726
727// Enter loopback mode and send a single ACL packet.
728TEST_P(BluetoothAidlTest, LoopbackModeSingleAcl) {
Myles Watsone1708c82023-01-18 17:07:58 -0800729 setBufferSizes();
730
731 enterLoopbackMode();
732
733 if (!acl_connection_handles.empty()) {
734 ASSERT_LT(0, max_acl_data_packet_length);
735 sendAndCheckAcl(1, max_acl_data_packet_length - 1,
736 acl_connection_handles[0]);
737 int acl_packets_sent = 1;
738 int completed_packets =
739 wait_for_completed_packets_event(acl_connection_handles[0]);
740 if (acl_packets_sent != completed_packets) {
741 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
742 acl_packets_sent, completed_packets);
743 }
744 }
745 ASSERT_GE(acl_cb_count, 1);
746}
747
748// Enter loopback mode and send command packets for bandwidth measurements.
749TEST_P(BluetoothAidlTest, LoopbackModeCommandBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800750 setBufferSizes();
751
752 enterLoopbackMode();
753
754 sendAndCheckHci(kNumHciCommandsBandwidth);
755}
756
757// Enter loopback mode and send SCO packets for bandwidth measurements.
758TEST_P(BluetoothAidlTest, LoopbackModeScoBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800759 setBufferSizes();
760 setSynchronousFlowControlEnable();
761
762 enterLoopbackMode();
763
764 if (!sco_connection_handles.empty()) {
765 ASSERT_LT(0, max_sco_data_packet_length);
766 sendAndCheckSco(kNumScoPacketsBandwidth, max_sco_data_packet_length,
767 sco_connection_handles[0]);
768 int sco_packets_sent = kNumScoPacketsBandwidth;
769 int completed_packets =
770 wait_for_completed_packets_event(sco_connection_handles[0]);
771 if (sco_packets_sent != completed_packets) {
772 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
773 sco_packets_sent, completed_packets);
774 }
775 }
776}
777
778// Enter loopback mode and send packets for ACL bandwidth measurements.
779TEST_P(BluetoothAidlTest, LoopbackModeAclBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800780 setBufferSizes();
781
782 enterLoopbackMode();
783
784 if (!acl_connection_handles.empty()) {
785 ASSERT_LT(0, max_acl_data_packet_length);
786 sendAndCheckAcl(kNumAclPacketsBandwidth, max_acl_data_packet_length - 1,
787 acl_connection_handles[0]);
788 int acl_packets_sent = kNumAclPacketsBandwidth;
789 int completed_packets =
790 wait_for_completed_packets_event(acl_connection_handles[0]);
791 if (acl_packets_sent != completed_packets) {
792 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
793 acl_packets_sent, completed_packets);
794 }
795 }
796}
797
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000798// Set all bits in the event mask
799TEST_P(BluetoothAidlTest, SetEventMask) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800800 std::vector<uint8_t> cmd;
801 ::bluetooth::packet::BitInserter bi{cmd};
802 uint64_t full_mask = UINT64_MAX;
803 ::bluetooth::hci::SetEventMaskBuilder::Create(full_mask)->Serialize(bi);
804 hci->sendHciCommand(cmd);
805 wait_for_command_complete_event(::bluetooth::hci::OpCode::SET_EVENT_MASK);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000806}
807
808// Set all bits in the LE event mask
809TEST_P(BluetoothAidlTest, SetLeEventMask) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800810 std::vector<uint8_t> cmd;
811 ::bluetooth::packet::BitInserter bi{cmd};
812 uint64_t full_mask = UINT64_MAX;
813 ::bluetooth::hci::LeSetEventMaskBuilder::Create(full_mask)->Serialize(bi);
814 hci->sendHciCommand(cmd);
815 wait_for_command_complete_event(::bluetooth::hci::OpCode::LE_SET_EVENT_MASK);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000816}
817
Myles Watson0daa1642023-01-26 15:58:28 -0800818// Call initialize twice, second one should fail.
819TEST_P(BluetoothAidlTest, CallInitializeTwice) {
820 class SecondCb
821 : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
822 public:
823 ndk::ScopedAStatus initializationComplete(Status status) {
824 EXPECT_EQ(status, Status::ALREADY_INITIALIZED);
825 init_promise.set_value();
826 return ScopedAStatus::ok();
827 };
828
829 ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& /*event*/) {
830 ADD_FAILURE();
831 return ScopedAStatus::ok();
832 };
833
834 ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& /*data*/) {
835 ADD_FAILURE();
836 return ScopedAStatus::ok();
837 };
838
839 ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& /*data*/) {
840 ADD_FAILURE();
841 return ScopedAStatus::ok();
842 };
843
844 ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& /*data*/) {
845 ADD_FAILURE();
846 return ScopedAStatus::ok();
847 };
848 std::promise<void> init_promise;
849 };
850
851 std::shared_ptr<SecondCb> second_cb = ndk::SharedRefBase::make<SecondCb>();
852 ASSERT_NE(second_cb, nullptr);
853
854 auto future = second_cb->init_promise.get_future();
855 ASSERT_TRUE(hci->initialize(second_cb).isOk());
856 auto status = future.wait_for(std::chrono::seconds(1));
857 ASSERT_EQ(status, std::future_status::ready);
858}
859
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000860GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
861INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
862 testing::ValuesIn(android::getAidlHalInstanceNames(
863 IBluetoothHci::descriptor)),
864 android::PrintInstanceNameToString);
865
866int main(int argc, char** argv) {
867 ABinderProcess_startThreadPool();
868 ::testing::InitGoogleTest(&argc, argv);
869 int status = RUN_ALL_TESTS();
870 ALOGI("Test result = %d", status);
871 return status;
872}