blob: 7f89853b44c10c82e31733c5716972a5c9b7d38c [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>
Dylan Tian8a6e09c2022-08-16 07:29:28 +000027
28#include <atomic>
29#include <chrono>
30#include <condition_variable>
31#include <future>
Dylan Tian8a6e09c2022-08-16 07:29:28 +000032#include <queue>
33#include <thread>
Jack Hedbceaca2023-03-27 18:06:38 -070034#include <utility>
Dylan Tian8a6e09c2022-08-16 07:29:28 +000035#include <vector>
36
Myles Watson51b8bae2023-01-27 14:22:24 -080037// TODO: Remove custom logging defines from PDL packets.
38#undef LOG_INFO
39#undef LOG_DEBUG
40#undef LOG_TAG
41#define LOG_TAG "VtsHalBluetooth"
42#include "hci/hci_packets.h"
43#include "packet/raw_builder.h"
44
Dylan Tian8a6e09c2022-08-16 07:29:28 +000045using aidl::android::hardware::bluetooth::IBluetoothHci;
46using aidl::android::hardware::bluetooth::IBluetoothHciCallbacks;
47using aidl::android::hardware::bluetooth::Status;
48using ndk::ScopedAStatus;
49using ndk::SpAIBinder;
50
Myles Watsone1708c82023-01-18 17:07:58 -080051static constexpr size_t kNumHciCommandsBandwidth = 100;
52static constexpr size_t kNumScoPacketsBandwidth = 100;
53static constexpr size_t kNumAclPacketsBandwidth = 100;
Dylan Tian8a6e09c2022-08-16 07:29:28 +000054static constexpr std::chrono::milliseconds kWaitForInitTimeout(2000);
55static constexpr std::chrono::milliseconds kWaitForHciEventTimeout(2000);
Myles Watsone1708c82023-01-18 17:07:58 -080056static constexpr std::chrono::milliseconds kWaitForScoDataTimeout(1000);
57static constexpr std::chrono::milliseconds kWaitForAclDataTimeout(1000);
Dylan Tian8a6e09c2022-08-16 07:29:28 +000058static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200);
59
Dylan Tian8a6e09c2022-08-16 07:29:28 +000060// To discard Qualcomm ACL debugging
61static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
62
63class ThroughputLogger {
64 public:
Jack Hedbceaca2023-03-27 18:06:38 -070065 explicit ThroughputLogger(std::string task)
Myles Watsone1708c82023-01-18 17:07:58 -080066 : total_bytes_(0),
Jack Hedbceaca2023-03-27 18:06:38 -070067 task_(std::move(task)),
Myles Watsone1708c82023-01-18 17:07:58 -080068 start_time_(std::chrono::steady_clock::now()) {}
Dylan Tian8a6e09c2022-08-16 07:29:28 +000069
70 ~ThroughputLogger() {
71 if (total_bytes_ == 0) {
72 return;
73 }
74 std::chrono::duration<double> duration =
75 std::chrono::steady_clock::now() - start_time_;
76 double s = duration.count();
77 if (s == 0) {
78 return;
79 }
80 double rate_kb = (static_cast<double>(total_bytes_) / s) / 1024;
81 ALOGD("%s %.1f KB/s (%zu bytes in %.3fs)", task_.c_str(), rate_kb,
82 total_bytes_, s);
83 }
84
85 void setTotalBytes(size_t total_bytes) { total_bytes_ = total_bytes; }
86
87 private:
88 size_t total_bytes_;
89 std::string task_;
90 std::chrono::steady_clock::time_point start_time_;
91};
92
93// The main test class for Bluetooth HAL.
94class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
95 public:
Jack Hedbceaca2023-03-27 18:06:38 -070096 void SetUp() override {
Dylan Tian8a6e09c2022-08-16 07:29:28 +000097 // currently test passthrough mode only
98 hci = IBluetoothHci::fromBinder(
99 SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
100 ASSERT_NE(hci, nullptr);
101 ALOGI("%s: getService() for bluetooth hci is %s", __func__,
102 hci->isRemote() ? "remote" : "local");
103
104 // Lambda function
105 auto on_binder_death = [](void* /*cookie*/) { FAIL(); };
106
107 bluetooth_hci_death_recipient =
108 AIBinder_DeathRecipient_new(on_binder_death);
109 ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
110 ASSERT_EQ(STATUS_OK,
111 AIBinder_linkToDeath(hci->asBinder().get(),
Jack Hedbceaca2023-03-27 18:06:38 -0700112 bluetooth_hci_death_recipient, nullptr));
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000113
114 hci_cb = ndk::SharedRefBase::make<BluetoothHciCallbacks>(*this);
115 ASSERT_NE(hci_cb, nullptr);
116
117 max_acl_data_packet_length = 0;
118 max_sco_data_packet_length = 0;
119 max_acl_data_packets = 0;
120 max_sco_data_packets = 0;
121
122 event_cb_count = 0;
123 acl_cb_count = 0;
124 sco_cb_count = 0;
125
126 ASSERT_TRUE(hci->initialize(hci_cb).isOk());
127 auto future = initialized_promise.get_future();
128 auto timeout_status = future.wait_for(kWaitForInitTimeout);
129 ASSERT_EQ(timeout_status, std::future_status::ready);
130 ASSERT_TRUE(future.get());
131 }
132
Jack Hedbceaca2023-03-27 18:06:38 -0700133 void TearDown() override {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000134 ALOGI("TearDown");
135 // Should not be checked in production code
136 ASSERT_TRUE(hci->close().isOk());
137 std::this_thread::sleep_for(kInterfaceCloseDelayMs);
138 handle_no_ops();
Myles Watsone1708c82023-01-18 17:07:58 -0800139 discard_qca_debugging();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000140 EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
141 EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
142 EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
143 EXPECT_EQ(static_cast<size_t>(0), iso_queue.size());
144 }
145
146 void setBufferSizes();
Myles Watsone1708c82023-01-18 17:07:58 -0800147 void setSynchronousFlowControlEnable();
148
149 // Functions called from within tests in loopback mode
150 void sendAndCheckHci(int num_packets);
151 void sendAndCheckSco(int num_packets, size_t size, uint16_t handle);
152 void sendAndCheckAcl(int num_packets, size_t size, uint16_t handle);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000153
154 // Helper functions to try to get a handle on verbosity
Myles Watsone1708c82023-01-18 17:07:58 -0800155 void enterLoopbackMode();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000156 void handle_no_ops();
Myles Watsone1708c82023-01-18 17:07:58 -0800157 void discard_qca_debugging();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000158 void wait_for_event(bool timeout_is_error);
Myles Watson51b8bae2023-01-27 14:22:24 -0800159 void wait_for_command_complete_event(::bluetooth::hci::OpCode opCode);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000160 int wait_for_completed_packets_event(uint16_t handle);
161
162 // A simple test implementation of BluetoothHciCallbacks.
163 class BluetoothHciCallbacks
164 : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
165 BluetoothAidlTest& parent_;
166
167 public:
Jack Hedbceaca2023-03-27 18:06:38 -0700168 explicit BluetoothHciCallbacks(BluetoothAidlTest& parent)
169 : parent_(parent){};
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000170
Jack Hedbceaca2023-03-27 18:06:38 -0700171 ~BluetoothHciCallbacks() override = default;
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000172
Jack Hedbceaca2023-03-27 18:06:38 -0700173 ndk::ScopedAStatus initializationComplete(Status status) override {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000174 parent_.initialized_promise.set_value(status == Status::SUCCESS);
175 ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
176 return ScopedAStatus::ok();
177 };
178
Jack Hedbceaca2023-03-27 18:06:38 -0700179 ndk::ScopedAStatus hciEventReceived(
180 const std::vector<uint8_t>& event) override {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000181 parent_.event_cb_count++;
182 parent_.event_queue.push(event);
183 ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
184 return ScopedAStatus::ok();
185 };
186
Jack Hedbceaca2023-03-27 18:06:38 -0700187 ndk::ScopedAStatus aclDataReceived(
188 const std::vector<uint8_t>& data) override {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000189 parent_.acl_cb_count++;
190 parent_.acl_queue.push(data);
191 return ScopedAStatus::ok();
192 };
193
Jack Hedbceaca2023-03-27 18:06:38 -0700194 ndk::ScopedAStatus scoDataReceived(
195 const std::vector<uint8_t>& data) override {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000196 parent_.sco_cb_count++;
197 parent_.sco_queue.push(data);
198 return ScopedAStatus::ok();
199 };
200
Jack Hedbceaca2023-03-27 18:06:38 -0700201 ndk::ScopedAStatus isoDataReceived(
202 const std::vector<uint8_t>& data) override {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000203 parent_.iso_cb_count++;
204 parent_.iso_queue.push(data);
205 return ScopedAStatus::ok();
206 };
207 };
208
209 template <class T>
210 class WaitQueue {
211 public:
Jack Hedbceaca2023-03-27 18:06:38 -0700212 WaitQueue() = default;
213 ;
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000214
215 virtual ~WaitQueue() = default;
216
217 bool empty() const {
218 std::lock_guard<std::mutex> lock(m_);
219 return q_.empty();
220 };
221
222 size_t size() const {
223 std::lock_guard<std::mutex> lock(m_);
224 return q_.size();
225 };
226
227 void push(const T& v) {
228 std::lock_guard<std::mutex> lock(m_);
229 q_.push(v);
230 ready_.notify_one();
231 };
232
233 bool pop(T& v) {
234 std::lock_guard<std::mutex> lock(m_);
235 if (q_.empty()) {
236 return false;
237 }
238 v = std::move(q_.front());
239 q_.pop();
240 return true;
241 };
242
Myles Watson51b8bae2023-01-27 14:22:24 -0800243 void pop() {
244 std::lock_guard<std::mutex> lock(m_);
245 if (q_.empty()) {
246 return;
247 }
248 q_.pop();
249 };
250
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000251 bool front(T& v) {
252 std::lock_guard<std::mutex> lock(m_);
253 if (q_.empty()) {
254 return false;
255 }
256 v = q_.front();
257 return true;
258 };
259
260 void wait() {
261 std::unique_lock<std::mutex> lock(m_);
262 while (q_.empty()) {
263 ready_.wait(lock);
264 }
265 };
266
267 bool waitWithTimeout(std::chrono::milliseconds timeout) {
268 std::unique_lock<std::mutex> lock(m_);
269 while (q_.empty()) {
270 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
271 return false;
272 }
273 }
274 return true;
275 };
276
277 bool tryPopWithTimeout(T& v, std::chrono::milliseconds timeout) {
278 std::unique_lock<std::mutex> lock(m_);
279 while (q_.empty()) {
280 if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
281 return false;
282 }
283 }
284 v = std::move(q_.front());
285 q_.pop();
286 return true;
287 };
288
289 private:
290 mutable std::mutex m_;
291 std::queue<T> q_;
292 std::condition_variable_any ready_;
293 };
294
295 std::shared_ptr<IBluetoothHci> hci;
296 std::shared_ptr<BluetoothHciCallbacks> hci_cb;
Jack Hedbceaca2023-03-27 18:06:38 -0700297 AIBinder_DeathRecipient* bluetooth_hci_death_recipient{};
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000298 WaitQueue<std::vector<uint8_t>> event_queue;
299 WaitQueue<std::vector<uint8_t>> acl_queue;
300 WaitQueue<std::vector<uint8_t>> sco_queue;
301 WaitQueue<std::vector<uint8_t>> iso_queue;
302
303 std::promise<bool> initialized_promise;
Jack Hedbceaca2023-03-27 18:06:38 -0700304 int event_cb_count{};
305 int sco_cb_count{};
306 int acl_cb_count{};
307 int iso_cb_count{};
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000308
Jack Hedbceaca2023-03-27 18:06:38 -0700309 int max_acl_data_packet_length{};
310 int max_sco_data_packet_length{};
311 int max_acl_data_packets{};
312 int max_sco_data_packets{};
Myles Watsone1708c82023-01-18 17:07:58 -0800313
314 std::vector<uint16_t> sco_connection_handles;
315 std::vector<uint16_t> acl_connection_handles;
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000316};
317
318// Discard NO-OPs from the event queue.
319void BluetoothAidlTest::handle_no_ops() {
320 while (!event_queue.empty()) {
321 std::vector<uint8_t> event;
322 event_queue.front(event);
Myles Watson51b8bae2023-01-27 14:22:24 -0800323 auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
324 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
325 std::make_shared<std::vector<uint8_t>>(event))));
326 auto status_view = ::bluetooth::hci::CommandCompleteView::Create(
327 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
328 std::make_shared<std::vector<uint8_t>>(event))));
329 bool is_complete_no_op =
330 complete_view.IsValid() &&
331 complete_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
332 bool is_status_no_op =
333 status_view.IsValid() &&
334 status_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
335 if (is_complete_no_op || is_status_no_op) {
336 event_queue.pop();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000337 } else {
338 break;
339 }
340 }
Myles Watsone1708c82023-01-18 17:07:58 -0800341}
342
343// Discard Qualcomm ACL debugging
344void BluetoothAidlTest::discard_qca_debugging() {
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000345 while (!acl_queue.empty()) {
346 std::vector<uint8_t> acl_packet;
347 acl_queue.front(acl_packet);
Myles Watson51b8bae2023-01-27 14:22:24 -0800348 auto acl_view =
349 ::bluetooth::hci::AclView::Create(::bluetooth::hci::PacketView<true>(
350 std::make_shared<std::vector<uint8_t>>(acl_packet)));
351 EXPECT_TRUE(acl_view.IsValid());
352 if (acl_view.GetHandle() == kAclHandleQcaDebugMessage) {
353 acl_queue.pop();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000354 } else {
355 break;
356 }
357 }
358}
359
360// Receive an event, discarding NO-OPs.
361void BluetoothAidlTest::wait_for_event(bool timeout_is_error = true) {
Myles Watsone1708c82023-01-18 17:07:58 -0800362 // Wait until we get something that's not a no-op.
363 while (true) {
364 bool event_ready = event_queue.waitWithTimeout(kWaitForHciEventTimeout);
365 ASSERT_TRUE(event_ready || !timeout_is_error);
366 if (event_queue.empty()) {
367 // waitWithTimeout timed out
368 return;
369 }
370 handle_no_ops();
371 if (!event_queue.empty()) {
372 // There's an event in the queue that's not a no-op.
373 return;
374 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000375 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000376}
377
378// Wait until a command complete is received.
379void BluetoothAidlTest::wait_for_command_complete_event(
Myles Watson51b8bae2023-01-27 14:22:24 -0800380 ::bluetooth::hci::OpCode opCode) {
Myles Watsone1708c82023-01-18 17:07:58 -0800381 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000382 std::vector<uint8_t> event;
Myles Watsone1708c82023-01-18 17:07:58 -0800383 ASSERT_FALSE(event_queue.empty());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000384 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800385 auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
386 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
387 std::make_shared<std::vector<uint8_t>>(event))));
388 ASSERT_TRUE(complete_view.IsValid());
389 ASSERT_EQ(complete_view.GetCommandOpCode(), opCode);
390 ASSERT_EQ(complete_view.GetPayload()[0],
391 static_cast<uint8_t>(::bluetooth::hci::ErrorCode::SUCCESS));
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000392}
393
394// Send the command to read the controller's buffer sizes.
395void BluetoothAidlTest::setBufferSizes() {
Myles Watson51b8bae2023-01-27 14:22:24 -0800396 std::vector<uint8_t> cmd;
397 ::bluetooth::packet::BitInserter bi{cmd};
398 ::bluetooth::hci::ReadBufferSizeBuilder::Create()->Serialize(bi);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000399 hci->sendHciCommand(cmd);
400
Myles Watsone1708c82023-01-18 17:07:58 -0800401 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000402 std::vector<uint8_t> event;
403 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800404 auto complete_view = ::bluetooth::hci::ReadBufferSizeCompleteView::Create(
405 ::bluetooth::hci::CommandCompleteView::Create(
406 ::bluetooth::hci::EventView::Create(
407 ::bluetooth::hci::PacketView<true>(
408 std::make_shared<std::vector<uint8_t>>(event)))));
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000409
Myles Watson51b8bae2023-01-27 14:22:24 -0800410 ASSERT_TRUE(complete_view.IsValid());
411 ASSERT_EQ(complete_view.GetStatus(), ::bluetooth::hci::ErrorCode::SUCCESS);
412 max_acl_data_packet_length = complete_view.GetAclDataPacketLength();
413 max_sco_data_packet_length = complete_view.GetSynchronousDataPacketLength();
414 max_acl_data_packets = complete_view.GetTotalNumAclDataPackets();
415 max_sco_data_packets = complete_view.GetTotalNumSynchronousDataPackets();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000416
417 ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
418 static_cast<int>(max_acl_data_packet_length),
419 static_cast<int>(max_acl_data_packets),
420 static_cast<int>(max_sco_data_packet_length),
421 static_cast<int>(max_sco_data_packets));
422}
423
Myles Watsone1708c82023-01-18 17:07:58 -0800424// Enable flow control packets for SCO
425void BluetoothAidlTest::setSynchronousFlowControlEnable() {
Myles Watson51b8bae2023-01-27 14:22:24 -0800426 std::vector<uint8_t> cmd;
427 ::bluetooth::packet::BitInserter bi{cmd};
428 ::bluetooth::hci::WriteSynchronousFlowControlEnableBuilder::Create(
429 ::bluetooth::hci::Enable::ENABLED)
430 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800431 hci->sendHciCommand(cmd);
432
Myles Watson51b8bae2023-01-27 14:22:24 -0800433 wait_for_command_complete_event(
434 ::bluetooth::hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE);
Myles Watsone1708c82023-01-18 17:07:58 -0800435}
436
437// Send an HCI command (in Loopback mode) and check the response.
438void BluetoothAidlTest::sendAndCheckHci(int num_packets) {
Jack Hedbceaca2023-03-27 18:06:38 -0700439 ThroughputLogger logger{__func__};
440 size_t command_size = 0;
Myles Watson51b8bae2023-01-27 14:22:24 -0800441 char new_name[] = "John Jacob Jingleheimer Schmidt ___________________";
442 size_t new_name_length = strlen(new_name);
Myles Watsone1708c82023-01-18 17:07:58 -0800443 for (int n = 0; n < num_packets; n++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800444 // The name to set is new_name
Jack Hedbceaca2023-03-27 18:06:38 -0700445 std::array<uint8_t, 248> name_array{};
Myles Watsone1708c82023-01-18 17:07:58 -0800446 for (size_t i = 0; i < new_name_length; i++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800447 name_array[i] = new_name[i];
Myles Watsone1708c82023-01-18 17:07:58 -0800448 }
449 // And the packet number
Myles Watson51b8bae2023-01-27 14:22:24 -0800450 char number[11] = "0000000000";
451 snprintf(number, sizeof(number), "%010d", static_cast<int>(n));
452 for (size_t i = new_name_length; i < new_name_length + sizeof(number) - 1;
453 i++) {
454 name_array[new_name_length + i] = number[i];
Myles Watsone1708c82023-01-18 17:07:58 -0800455 }
Myles Watson51b8bae2023-01-27 14:22:24 -0800456 std::vector<uint8_t> write_name;
457 ::bluetooth::packet::BitInserter bi{write_name};
458 ::bluetooth::hci::WriteLocalNameBuilder::Create(name_array)->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800459 hci->sendHciCommand(write_name);
460
461 // Check the loopback of the HCI packet
462 ASSERT_NO_FATAL_FAILURE(wait_for_event());
463
464 std::vector<uint8_t> event;
465 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800466 auto event_view = ::bluetooth::hci::LoopbackCommandView::Create(
467 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
468 std::make_shared<std::vector<uint8_t>>(event))));
469 ASSERT_TRUE(event_view.IsValid());
470 std::vector<uint8_t> looped_back_command{event_view.GetPayload().begin(),
471 event_view.GetPayload().end()};
472 ASSERT_EQ(looped_back_command, write_name);
Myles Watsone1708c82023-01-18 17:07:58 -0800473
474 if (n == num_packets - 1) {
475 command_size = write_name.size();
476 }
Myles Watsone1708c82023-01-18 17:07:58 -0800477 }
478 logger.setTotalBytes(command_size * num_packets * 2);
479}
480
481// Send a SCO data packet (in Loopback mode) and check the response.
482void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size,
483 uint16_t handle) {
Jack Hedbceaca2023-03-27 18:06:38 -0700484 ThroughputLogger logger{__func__};
Myles Watsone1708c82023-01-18 17:07:58 -0800485 for (int n = 0; n < num_packets; n++) {
486 // Send a SCO packet
487 std::vector<uint8_t> sco_packet;
Myles Watson51b8bae2023-01-27 14:22:24 -0800488 std::vector<uint8_t> payload;
Myles Watsone1708c82023-01-18 17:07:58 -0800489 for (size_t i = 0; i < size; i++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800490 payload.push_back(static_cast<uint8_t>(i + n));
Myles Watsone1708c82023-01-18 17:07:58 -0800491 }
Myles Watson51b8bae2023-01-27 14:22:24 -0800492 ::bluetooth::packet::BitInserter bi{sco_packet};
493 ::bluetooth::hci::ScoBuilder::Create(
494 handle, ::bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED, payload)
495 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800496 hci->sendScoData(sco_packet);
497
498 // Check the loopback of the SCO packet
499 std::vector<uint8_t> sco_loopback;
500 ASSERT_TRUE(
501 sco_queue.tryPopWithTimeout(sco_loopback, kWaitForScoDataTimeout));
502
Myles Watson51b8bae2023-01-27 14:22:24 -0800503 ASSERT_EQ(sco_packet, sco_loopback);
Myles Watsone1708c82023-01-18 17:07:58 -0800504 }
505 logger.setTotalBytes(num_packets * size * 2);
506}
507
508// Send an ACL data packet (in Loopback mode) and check the response.
509void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size,
510 uint16_t handle) {
Jack Hedbceaca2023-03-27 18:06:38 -0700511 ThroughputLogger logger{__func__};
Myles Watsone1708c82023-01-18 17:07:58 -0800512 for (int n = 0; n < num_packets; n++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800513 // Send an ACL packet with counting data
514 auto payload = std::make_unique<::bluetooth::packet::RawBuilder>();
Myles Watsone1708c82023-01-18 17:07:58 -0800515 for (size_t i = 0; i < size; i++) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800516 payload->AddOctets1(static_cast<uint8_t>(i + n));
Myles Watsone1708c82023-01-18 17:07:58 -0800517 }
Myles Watson51b8bae2023-01-27 14:22:24 -0800518 std::vector<uint8_t> acl_packet;
519 ::bluetooth::packet::BitInserter bi{acl_packet};
520 ::bluetooth::hci::AclBuilder::Create(
521 handle,
522 ::bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE,
523 ::bluetooth::hci::BroadcastFlag::POINT_TO_POINT, std::move(payload))
524 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800525 hci->sendAclData(acl_packet);
526
527 std::vector<uint8_t> acl_loopback;
528 // Check the loopback of the ACL packet
529 ASSERT_TRUE(
530 acl_queue.tryPopWithTimeout(acl_loopback, kWaitForAclDataTimeout));
531
Myles Watson51b8bae2023-01-27 14:22:24 -0800532 ASSERT_EQ(acl_packet, acl_loopback);
Myles Watsone1708c82023-01-18 17:07:58 -0800533 }
534 logger.setTotalBytes(num_packets * size * 2);
535}
536
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000537// Return the number of completed packets reported by the controller.
538int BluetoothAidlTest::wait_for_completed_packets_event(uint16_t handle) {
539 int packets_processed = 0;
Myles Watson65b47f52023-01-26 12:59:06 -0800540 while (true) {
541 // There should be at least one event.
542 wait_for_event(packets_processed == 0);
543 if (event_queue.empty()) {
544 if (packets_processed == 0) {
545 ALOGW("%s: waitForBluetoothCallback timed out.", __func__);
546 }
547 return packets_processed;
548 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000549 std::vector<uint8_t> event;
550 EXPECT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800551 auto event_view = ::bluetooth::hci::NumberOfCompletedPacketsView::Create(
552 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
553 std::make_shared<std::vector<uint8_t>>(event))));
554 if (!event_view.IsValid()) {
555 ADD_FAILURE();
556 return packets_processed;
557 }
558 auto completed_packets = event_view.GetCompletedPackets();
Jack Hedbceaca2023-03-27 18:06:38 -0700559 for (const auto& entry : completed_packets) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800560 EXPECT_EQ(handle, entry.connection_handle_);
561 packets_processed += entry.host_num_of_completed_packets_;
562 }
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000563 }
564 return packets_processed;
565}
566
Myles Watsone1708c82023-01-18 17:07:58 -0800567// Send local loopback command and initialize SCO and ACL handles.
568void BluetoothAidlTest::enterLoopbackMode() {
Myles Watson51b8bae2023-01-27 14:22:24 -0800569 std::vector<uint8_t> cmd;
570 ::bluetooth::packet::BitInserter bi{cmd};
571 ::bluetooth::hci::WriteLoopbackModeBuilder::Create(
572 bluetooth::hci::LoopbackMode::ENABLE_LOCAL)
573 ->Serialize(bi);
Myles Watsone1708c82023-01-18 17:07:58 -0800574 hci->sendHciCommand(cmd);
575
576 // Receive connection complete events with data channels
577 int connection_event_count = 0;
578 bool command_complete_received = false;
579 while (true) {
580 wait_for_event(false);
581 if (event_queue.empty()) {
582 // Fail if there was no event received or no connections completed.
583 ASSERT_TRUE(command_complete_received);
584 ASSERT_LT(0, connection_event_count);
585 return;
586 }
587 std::vector<uint8_t> event;
588 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800589 auto event_view =
590 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
591 std::make_shared<std::vector<uint8_t>>(event)));
592 ASSERT_TRUE(event_view.IsValid());
Myles Watsone1708c82023-01-18 17:07:58 -0800593
Myles Watson51b8bae2023-01-27 14:22:24 -0800594 if (event_view.GetEventCode() ==
595 ::bluetooth::hci::EventCode::CONNECTION_COMPLETE) {
596 auto complete_view =
597 ::bluetooth::hci::ConnectionCompleteView::Create(event_view);
598 ASSERT_TRUE(complete_view.IsValid());
599 switch (complete_view.GetLinkType()) {
600 case ::bluetooth::hci::LinkType::ACL:
601 acl_connection_handles.push_back(complete_view.GetConnectionHandle());
602 break;
603 case ::bluetooth::hci::LinkType::SCO:
604 sco_connection_handles.push_back(complete_view.GetConnectionHandle());
605 break;
606 default:
607 ASSERT_EQ(complete_view.GetLinkType(),
608 ::bluetooth::hci::LinkType::ACL);
Myles Watsone1708c82023-01-18 17:07:58 -0800609 }
Myles Watsone1708c82023-01-18 17:07:58 -0800610 connection_event_count++;
611 } else {
Myles Watson51b8bae2023-01-27 14:22:24 -0800612 auto command_complete_view =
613 ::bluetooth::hci::WriteLoopbackModeCompleteView::Create(
614 ::bluetooth::hci::CommandCompleteView::Create(event_view));
615 ASSERT_TRUE(command_complete_view.IsValid());
616 ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
617 command_complete_view.GetStatus());
Myles Watsone1708c82023-01-18 17:07:58 -0800618 command_complete_received = true;
619 }
620 }
621}
622
623// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
624TEST_P(BluetoothAidlTest, InitializeAndClose) {}
625
626// Send an HCI Reset with sendHciCommand and wait for a command complete event.
Myles Watson65b47f52023-01-26 12:59:06 -0800627TEST_P(BluetoothAidlTest, HciReset) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800628 std::vector<uint8_t> reset;
629 ::bluetooth::packet::BitInserter bi{reset};
630 ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi);
Myles Watson65b47f52023-01-26 12:59:06 -0800631 hci->sendHciCommand(reset);
632
Myles Watson51b8bae2023-01-27 14:22:24 -0800633 wait_for_command_complete_event(::bluetooth::hci::OpCode::RESET);
Myles Watson65b47f52023-01-26 12:59:06 -0800634}
Myles Watsone1708c82023-01-18 17:07:58 -0800635
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000636// Read and check the HCI version of the controller.
637TEST_P(BluetoothAidlTest, HciVersionTest) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800638 std::vector<uint8_t> cmd;
639 ::bluetooth::packet::BitInserter bi{cmd};
640 ::bluetooth::hci::ReadLocalVersionInformationBuilder::Create()->Serialize(bi);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000641 hci->sendHciCommand(cmd);
642
Myles Watsone1708c82023-01-18 17:07:58 -0800643 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000644
645 std::vector<uint8_t> event;
646 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800647 auto complete_view =
648 ::bluetooth::hci::ReadLocalVersionInformationCompleteView::Create(
649 ::bluetooth::hci::CommandCompleteView::Create(
650 ::bluetooth::hci::EventView::Create(
651 ::bluetooth::hci::PacketView<true>(
652 std::make_shared<std::vector<uint8_t>>(event)))));
653 ASSERT_TRUE(complete_view.IsValid());
654 ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, complete_view.GetStatus());
655 auto version = complete_view.GetLocalVersionInformation();
656 ASSERT_LE(::bluetooth::hci::HciVersion::V_3_0, version.hci_version_);
657 ASSERT_LE(::bluetooth::hci::LmpVersion::V_3_0, version.lmp_version_);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000658}
659
660// Send an unknown HCI command and wait for the error message.
661TEST_P(BluetoothAidlTest, HciUnknownCommand) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800662 std::vector<uint8_t> cmd;
663 ::bluetooth::packet::BitInserter bi{cmd};
664 ::bluetooth::hci::CommandBuilder::Create(
665 static_cast<::bluetooth::hci::OpCode>(0x3cff),
666 std::make_unique<::bluetooth::packet::RawBuilder>())
667 ->Serialize(bi);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000668 hci->sendHciCommand(cmd);
669
Myles Watsone1708c82023-01-18 17:07:58 -0800670 ASSERT_NO_FATAL_FAILURE(wait_for_event());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000671
672 std::vector<uint8_t> event;
673 ASSERT_TRUE(event_queue.pop(event));
Myles Watson51b8bae2023-01-27 14:22:24 -0800674 auto event_view =
675 ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
676 std::make_shared<std::vector<uint8_t>>(event)));
677 ASSERT_TRUE(event_view.IsValid());
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000678
Myles Watson51b8bae2023-01-27 14:22:24 -0800679 switch (event_view.GetEventCode()) {
680 case ::bluetooth::hci::EventCode::COMMAND_COMPLETE: {
681 auto command_complete =
682 ::bluetooth::hci::CommandCompleteView::Create(event_view);
683 ASSERT_TRUE(command_complete.IsValid());
684 ASSERT_EQ(command_complete.GetPayload()[0],
685 static_cast<uint8_t>(
686 ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
687 } break;
688 case ::bluetooth::hci::EventCode::COMMAND_STATUS: {
689 auto command_status =
690 ::bluetooth::hci::CommandStatusView::Create(event_view);
691 ASSERT_TRUE(command_status.IsValid());
692 ASSERT_EQ(command_status.GetStatus(),
693 ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
694 } break;
695 default:
696 ADD_FAILURE();
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000697 }
698}
699
Myles Watsone1708c82023-01-18 17:07:58 -0800700// Enter loopback mode, but don't send any packets.
Myles Watson65b47f52023-01-26 12:59:06 -0800701TEST_P(BluetoothAidlTest, WriteLoopbackMode) { enterLoopbackMode(); }
Myles Watsone1708c82023-01-18 17:07:58 -0800702
703// Enter loopback mode and send a single command.
704TEST_P(BluetoothAidlTest, LoopbackModeSingleCommand) {
Myles Watsone1708c82023-01-18 17:07:58 -0800705 setBufferSizes();
706
707 enterLoopbackMode();
708
709 sendAndCheckHci(1);
710}
711
712// Enter loopback mode and send a single SCO packet.
713TEST_P(BluetoothAidlTest, LoopbackModeSingleSco) {
Myles Watsone1708c82023-01-18 17:07:58 -0800714 setBufferSizes();
715 setSynchronousFlowControlEnable();
716
717 enterLoopbackMode();
718
719 if (!sco_connection_handles.empty()) {
720 ASSERT_LT(0, max_sco_data_packet_length);
721 sendAndCheckSco(1, max_sco_data_packet_length, sco_connection_handles[0]);
722 int sco_packets_sent = 1;
723 int completed_packets =
724 wait_for_completed_packets_event(sco_connection_handles[0]);
725 if (sco_packets_sent != completed_packets) {
726 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
727 sco_packets_sent, completed_packets);
728 }
729 }
730}
731
732// Enter loopback mode and send a single ACL packet.
733TEST_P(BluetoothAidlTest, LoopbackModeSingleAcl) {
Myles Watsone1708c82023-01-18 17:07:58 -0800734 setBufferSizes();
735
736 enterLoopbackMode();
737
738 if (!acl_connection_handles.empty()) {
739 ASSERT_LT(0, max_acl_data_packet_length);
740 sendAndCheckAcl(1, max_acl_data_packet_length - 1,
741 acl_connection_handles[0]);
742 int acl_packets_sent = 1;
743 int completed_packets =
744 wait_for_completed_packets_event(acl_connection_handles[0]);
745 if (acl_packets_sent != completed_packets) {
746 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
747 acl_packets_sent, completed_packets);
748 }
749 }
750 ASSERT_GE(acl_cb_count, 1);
751}
752
753// Enter loopback mode and send command packets for bandwidth measurements.
754TEST_P(BluetoothAidlTest, LoopbackModeCommandBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800755 setBufferSizes();
756
757 enterLoopbackMode();
758
759 sendAndCheckHci(kNumHciCommandsBandwidth);
760}
761
762// Enter loopback mode and send SCO packets for bandwidth measurements.
763TEST_P(BluetoothAidlTest, LoopbackModeScoBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800764 setBufferSizes();
765 setSynchronousFlowControlEnable();
766
767 enterLoopbackMode();
768
769 if (!sco_connection_handles.empty()) {
770 ASSERT_LT(0, max_sco_data_packet_length);
771 sendAndCheckSco(kNumScoPacketsBandwidth, max_sco_data_packet_length,
772 sco_connection_handles[0]);
773 int sco_packets_sent = kNumScoPacketsBandwidth;
774 int completed_packets =
775 wait_for_completed_packets_event(sco_connection_handles[0]);
776 if (sco_packets_sent != completed_packets) {
777 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
778 sco_packets_sent, completed_packets);
779 }
780 }
781}
782
783// Enter loopback mode and send packets for ACL bandwidth measurements.
784TEST_P(BluetoothAidlTest, LoopbackModeAclBandwidth) {
Myles Watsone1708c82023-01-18 17:07:58 -0800785 setBufferSizes();
786
787 enterLoopbackMode();
788
789 if (!acl_connection_handles.empty()) {
790 ASSERT_LT(0, max_acl_data_packet_length);
791 sendAndCheckAcl(kNumAclPacketsBandwidth, max_acl_data_packet_length - 1,
792 acl_connection_handles[0]);
793 int acl_packets_sent = kNumAclPacketsBandwidth;
794 int completed_packets =
795 wait_for_completed_packets_event(acl_connection_handles[0]);
796 if (acl_packets_sent != completed_packets) {
797 ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
798 acl_packets_sent, completed_packets);
799 }
800 }
801}
802
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000803// Set all bits in the event mask
804TEST_P(BluetoothAidlTest, SetEventMask) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800805 std::vector<uint8_t> cmd;
806 ::bluetooth::packet::BitInserter bi{cmd};
807 uint64_t full_mask = UINT64_MAX;
808 ::bluetooth::hci::SetEventMaskBuilder::Create(full_mask)->Serialize(bi);
809 hci->sendHciCommand(cmd);
810 wait_for_command_complete_event(::bluetooth::hci::OpCode::SET_EVENT_MASK);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000811}
812
813// Set all bits in the LE event mask
814TEST_P(BluetoothAidlTest, SetLeEventMask) {
Myles Watson51b8bae2023-01-27 14:22:24 -0800815 std::vector<uint8_t> cmd;
816 ::bluetooth::packet::BitInserter bi{cmd};
817 uint64_t full_mask = UINT64_MAX;
818 ::bluetooth::hci::LeSetEventMaskBuilder::Create(full_mask)->Serialize(bi);
819 hci->sendHciCommand(cmd);
820 wait_for_command_complete_event(::bluetooth::hci::OpCode::LE_SET_EVENT_MASK);
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000821}
822
Myles Watson0daa1642023-01-26 15:58:28 -0800823// Call initialize twice, second one should fail.
824TEST_P(BluetoothAidlTest, CallInitializeTwice) {
825 class SecondCb
826 : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
827 public:
Jack Hedbceaca2023-03-27 18:06:38 -0700828 ndk::ScopedAStatus initializationComplete(Status status) override {
Myles Watson0daa1642023-01-26 15:58:28 -0800829 EXPECT_EQ(status, Status::ALREADY_INITIALIZED);
830 init_promise.set_value();
831 return ScopedAStatus::ok();
832 };
833
Jack Hedbceaca2023-03-27 18:06:38 -0700834 ndk::ScopedAStatus hciEventReceived(
835 const std::vector<uint8_t>& /*event*/) override {
Myles Watson0daa1642023-01-26 15:58:28 -0800836 ADD_FAILURE();
837 return ScopedAStatus::ok();
838 };
839
Jack Hedbceaca2023-03-27 18:06:38 -0700840 ndk::ScopedAStatus aclDataReceived(
841 const std::vector<uint8_t>& /*data*/) override {
Myles Watson0daa1642023-01-26 15:58:28 -0800842 ADD_FAILURE();
843 return ScopedAStatus::ok();
844 };
845
Jack Hedbceaca2023-03-27 18:06:38 -0700846 ndk::ScopedAStatus scoDataReceived(
847 const std::vector<uint8_t>& /*data*/) override {
Myles Watson0daa1642023-01-26 15:58:28 -0800848 ADD_FAILURE();
849 return ScopedAStatus::ok();
850 };
851
Jack Hedbceaca2023-03-27 18:06:38 -0700852 ndk::ScopedAStatus isoDataReceived(
853 const std::vector<uint8_t>& /*data*/) override {
Myles Watson0daa1642023-01-26 15:58:28 -0800854 ADD_FAILURE();
855 return ScopedAStatus::ok();
856 };
857 std::promise<void> init_promise;
858 };
859
860 std::shared_ptr<SecondCb> second_cb = ndk::SharedRefBase::make<SecondCb>();
861 ASSERT_NE(second_cb, nullptr);
862
863 auto future = second_cb->init_promise.get_future();
864 ASSERT_TRUE(hci->initialize(second_cb).isOk());
865 auto status = future.wait_for(std::chrono::seconds(1));
866 ASSERT_EQ(status, std::future_status::ready);
867}
868
Dylan Tian8a6e09c2022-08-16 07:29:28 +0000869GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
870INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
871 testing::ValuesIn(android::getAidlHalInstanceNames(
872 IBluetoothHci::descriptor)),
873 android::PrintInstanceNameToString);
874
875int main(int argc, char** argv) {
876 ABinderProcess_startThreadPool();
877 ::testing::InitGoogleTest(&argc, argv);
878 int status = RUN_ALL_TESTS();
879 ALOGI("Test result = %d", status);
880 return status;
881}