1 /*
2  * Copyright 2020 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 "hci/acl_manager/round_robin_scheduler.h"
18 
19 #include <com_android_bluetooth_flags.h>
20 #include <gtest/gtest.h>
21 
22 #include "common/bidi_queue.h"
23 #include "common/callback.h"
24 #include "hci/controller.h"
25 #include "hci/hci_packets.h"
26 #include "os/handler.h"
27 #include "packet/raw_builder.h"
28 
29 using ::bluetooth::common::BidiQueue;
30 using ::bluetooth::common::Callback;
31 using ::bluetooth::os::Handler;
32 using ::bluetooth::os::Thread;
33 
34 using namespace std::chrono_literals;
35 
36 namespace bluetooth {
37 namespace hci {
38 namespace acl_manager {
39 namespace {
40 
41 class TestController : public Controller {
42 public:
GetNumAclPacketBuffers() const43   uint16_t GetNumAclPacketBuffers() const { return max_acl_packet_credits_; }
44 
GetAclPacketLength() const45   uint16_t GetAclPacketLength() const { return hci_mtu_; }
46 
GetLeBufferSize() const47   LeBufferSize GetLeBufferSize() const {
48     LeBufferSize le_buffer_size;
49     le_buffer_size.le_data_packet_length_ = le_hci_mtu_;
50     le_buffer_size.total_num_le_packets_ = le_max_acl_packet_credits_;
51     return le_buffer_size;
52   }
53 
RegisterCompletedAclPacketsCallback(CompletedAclPacketsCallback cb)54   void RegisterCompletedAclPacketsCallback(CompletedAclPacketsCallback cb) {
55     acl_credits_callback_ = cb;
56   }
57 
SendCompletedAclPacketsCallback(uint16_t handle,uint16_t credits)58   void SendCompletedAclPacketsCallback(uint16_t handle, uint16_t credits) {
59     acl_credits_callback_(handle, credits);
60   }
61 
UnregisterCompletedAclPacketsCallback()62   void UnregisterCompletedAclPacketsCallback() { acl_credits_callback_ = {}; }
63 
64   const uint16_t max_acl_packet_credits_ = 10;
65   const uint16_t hci_mtu_ = 1024;
66   const uint16_t le_max_acl_packet_credits_ = 15;
67   const uint16_t le_hci_mtu_ = 27;
68 
69 private:
70   CompletedAclPacketsCallback acl_credits_callback_;
71 };
72 
73 class RoundRobinSchedulerTest : public ::testing::Test {
74 public:
SetUp()75   void SetUp() override {
76     thread_ = new Thread("thread", Thread::Priority::NORMAL);
77     handler_ = new Handler(thread_);
78     controller_ = new TestController();
79     round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_queue_.GetUpEnd());
80     hci_queue_.GetDownEnd()->RegisterDequeue(
81             handler_,
82             common::Bind(&RoundRobinSchedulerTest::HciDownEndDequeue, common::Unretained(this)));
83   }
84 
TearDown()85   void TearDown() override {
86     hci_queue_.GetDownEnd()->UnregisterDequeue();
87     delete round_robin_scheduler_;
88     delete controller_;
89     handler_->Clear();
90     delete handler_;
91     delete thread_;
92   }
93 
sync_handler()94   void sync_handler() {
95     log::assert_that(thread_ != nullptr, "assert failed: thread_ != nullptr");
96     log::assert_that(thread_->GetReactor()->WaitForIdle(2s),
97                      "assert failed: thread_->GetReactor()->WaitForIdle(2s)");
98   }
99 
EnqueueAclUpEnd(AclConnection::QueueUpEnd * queue_up_end,std::vector<uint8_t> packet)100   void EnqueueAclUpEnd(AclConnection::QueueUpEnd* queue_up_end, std::vector<uint8_t> packet) {
101     if (enqueue_promise_ != nullptr) {
102       enqueue_future_->wait();
103     }
104     enqueue_promise_ = std::make_unique<std::promise<void>>();
105     enqueue_future_ = std::make_unique<std::future<void>>(enqueue_promise_->get_future());
106     queue_up_end->RegisterEnqueue(handler_,
107                                   common::Bind(&RoundRobinSchedulerTest::enqueue_callback,
108                                                common::Unretained(this), queue_up_end, packet));
109   }
110 
enqueue_callback(AclConnection::QueueUpEnd * queue_up_end,std::vector<uint8_t> packet)111   std::unique_ptr<packet::BasePacketBuilder> enqueue_callback(
112           AclConnection::QueueUpEnd* queue_up_end, std::vector<uint8_t> packet) {
113     auto packet_one = std::make_unique<packet::RawBuilder>(2000);
114     packet_one->AddOctets(packet);
115     queue_up_end->UnregisterEnqueue();
116     enqueue_promise_->set_value();
117     return packet_one;
118   }
119 
HciDownEndDequeue()120   void HciDownEndDequeue() {
121     auto packet = hci_queue_.GetDownEnd()->TryDequeue();
122     // Convert from a Builder to a View
123     auto bytes = std::make_shared<std::vector<uint8_t>>();
124     bluetooth::packet::BitInserter i(*bytes);
125     bytes->reserve(packet->size());
126     packet->Serialize(i);
127     auto packet_view = bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian>(bytes);
128     AclView acl_packet_view = AclView::Create(packet_view);
129     ASSERT_TRUE(acl_packet_view.IsValid());
130     PacketView<true> count_view = acl_packet_view.GetPayload();
131     sent_acl_packets_.push(acl_packet_view);
132 
133     packet_count_--;
134     if (packet_count_ == 0) {
135       std::promise<void>* prom = packet_promise_.release();
136       prom->set_value();
137       delete prom;
138     }
139   }
140 
VerifyPacket(uint16_t handle,std::vector<uint8_t> packet)141   void VerifyPacket(uint16_t handle, std::vector<uint8_t> packet) {
142     auto acl_packet_view = sent_acl_packets_.front();
143     ASSERT_EQ(handle, acl_packet_view.GetHandle());
144     auto payload = acl_packet_view.GetPayload();
145     for (size_t i = 0; i < payload.size(); i++) {
146       ASSERT_EQ(payload[i], packet[i]);
147     }
148     sent_acl_packets_.pop();
149   }
150 
SetPacketFuture(uint16_t count)151   void SetPacketFuture(uint16_t count) {
152     ASSERT_EQ(packet_promise_, nullptr) << "Promises, Promises, ... Only one at a time.";
153     packet_count_ = count;
154     packet_promise_ = std::make_unique<std::promise<void>>();
155     packet_future_ = std::make_unique<std::future<void>>(packet_promise_->get_future());
156   }
157 
158   BidiQueue<AclView, AclBuilder> hci_queue_{3};
159   Thread* thread_;
160   Handler* handler_;
161   TestController* controller_;
162   RoundRobinScheduler* round_robin_scheduler_;
163   std::queue<AclView> sent_acl_packets_;
164   uint16_t packet_count_;
165   std::unique_ptr<std::promise<void>> packet_promise_;
166   std::unique_ptr<std::future<void>> packet_future_;
167   std::unique_ptr<std::promise<void>> enqueue_promise_;
168   std::unique_ptr<std::future<void>> enqueue_future_;
169 };
170 
TEST_F(RoundRobinSchedulerTest,startup_teardown)171 TEST_F(RoundRobinSchedulerTest, startup_teardown) {}
172 
TEST_F(RoundRobinSchedulerTest,register_unregister_connection)173 TEST_F(RoundRobinSchedulerTest, register_unregister_connection) {
174   uint16_t handle = 0x01;
175   auto connection_queue = std::make_shared<AclConnection::Queue>(10);
176   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
177                                    connection_queue);
178   round_robin_scheduler_->Unregister(handle);
179 }
180 
TEST_F(RoundRobinSchedulerTest,buffer_packet)181 TEST_F(RoundRobinSchedulerTest, buffer_packet) {
182   uint16_t handle = 0x01;
183   auto connection_queue = std::make_shared<AclConnection::Queue>(10);
184   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
185                                    connection_queue);
186 
187   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(2));
188   AclConnection::QueueUpEnd* queue_up_end = connection_queue->GetUpEnd();
189   std::vector<uint8_t> packet1 = {0x01, 0x02, 0x03};
190   std::vector<uint8_t> packet2 = {0x04, 0x05, 0x06};
191   EnqueueAclUpEnd(queue_up_end, packet1);
192   EnqueueAclUpEnd(queue_up_end, packet2);
193 
194   packet_future_->wait();
195   VerifyPacket(handle, packet1);
196   VerifyPacket(handle, packet2);
197   ASSERT_EQ(round_robin_scheduler_->GetCredits(), controller_->max_acl_packet_credits_ - 2);
198 
199   round_robin_scheduler_->Unregister(handle);
200 }
201 
TEST_F(RoundRobinSchedulerTest,buffer_packet_from_two_connections)202 TEST_F(RoundRobinSchedulerTest, buffer_packet_from_two_connections) {
203   uint16_t handle = 0x01;
204   uint16_t le_handle = 0x02;
205   auto connection_queue = std::make_shared<AclConnection::Queue>(10);
206   auto le_connection_queue = std::make_shared<AclConnection::Queue>(10);
207 
208   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
209                                    connection_queue);
210   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, le_handle,
211                                    le_connection_queue);
212 
213   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(2));
214   AclConnection::QueueUpEnd* queue_up_end = connection_queue->GetUpEnd();
215   AclConnection::QueueUpEnd* le_queue_up_end = le_connection_queue->GetUpEnd();
216   std::vector<uint8_t> packet = {0x01, 0x02, 0x03};
217   std::vector<uint8_t> le_packet = {0x04, 0x05, 0x06};
218   EnqueueAclUpEnd(le_queue_up_end, le_packet);
219   EnqueueAclUpEnd(queue_up_end, packet);
220 
221   packet_future_->wait();
222   VerifyPacket(le_handle, le_packet);
223   VerifyPacket(handle, packet);
224   ASSERT_EQ(round_robin_scheduler_->GetCredits(), controller_->max_acl_packet_credits_ - 1);
225   ASSERT_EQ(round_robin_scheduler_->GetLeCredits(), controller_->le_max_acl_packet_credits_ - 1);
226 
227   round_robin_scheduler_->Unregister(handle);
228   round_robin_scheduler_->Unregister(le_handle);
229 }
230 
TEST_F(RoundRobinSchedulerTest,do_not_register_when_credits_is_zero)231 TEST_F(RoundRobinSchedulerTest, do_not_register_when_credits_is_zero) {
232   uint16_t handle = 0x01;
233   auto connection_queue = std::make_shared<AclConnection::Queue>(15);
234   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
235                                    connection_queue);
236 
237   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(10));
238   AclConnection::QueueUpEnd* queue_up_end = connection_queue->GetUpEnd();
239   for (uint8_t i = 0; i < 15; i++) {
240     std::vector<uint8_t> packet = {0x01, 0x02, 0x03, i};
241     EnqueueAclUpEnd(queue_up_end, packet);
242   }
243 
244   packet_future_->wait();
245   for (uint8_t i = 0; i < 10; i++) {
246     std::vector<uint8_t> packet = {0x01, 0x02, 0x03, i};
247     VerifyPacket(handle, packet);
248   }
249   ASSERT_EQ(round_robin_scheduler_->GetCredits(), 0);
250 
251   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(5));
252   controller_->SendCompletedAclPacketsCallback(0x01, 10);
253   sync_handler();
254   packet_future_->wait();
255   for (uint8_t i = 10; i < 15; i++) {
256     std::vector<uint8_t> packet = {0x01, 0x02, 0x03, i};
257     VerifyPacket(handle, packet);
258   }
259   ASSERT_EQ(round_robin_scheduler_->GetCredits(), 5);
260 
261   round_robin_scheduler_->Unregister(handle);
262 }
263 
TEST_F(RoundRobinSchedulerTest,reveived_completed_callback_with_unknown_handle)264 TEST_F(RoundRobinSchedulerTest, reveived_completed_callback_with_unknown_handle) {
265   controller_->SendCompletedAclPacketsCallback(0x00, 1);
266   sync_handler();
267   EXPECT_EQ(round_robin_scheduler_->GetCredits(), controller_->max_acl_packet_credits_);
268   EXPECT_EQ(round_robin_scheduler_->GetLeCredits(), controller_->le_max_acl_packet_credits_);
269 }
270 
TEST_F(RoundRobinSchedulerTest,buffer_packet_intervally)271 TEST_F(RoundRobinSchedulerTest, buffer_packet_intervally) {
272   uint16_t handle1 = 0x01;
273   uint16_t handle2 = 0x02;
274   uint16_t le_handle1 = 0x03;
275   uint16_t le_handle2 = 0x04;
276   auto connection_queue1 = std::make_shared<AclConnection::Queue>(10);
277   auto connection_queue2 = std::make_shared<AclConnection::Queue>(10);
278   auto le_connection_queue1 = std::make_shared<AclConnection::Queue>(10);
279   auto le_connection_queue2 = std::make_shared<AclConnection::Queue>(10);
280 
281   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(18));
282   AclConnection::QueueUpEnd* queue_up_end1 = connection_queue1->GetUpEnd();
283   AclConnection::QueueUpEnd* queue_up_end2 = connection_queue2->GetUpEnd();
284   AclConnection::QueueUpEnd* le_queue_up_end1 = le_connection_queue1->GetUpEnd();
285   AclConnection::QueueUpEnd* le_queue_up_end2 = le_connection_queue2->GetUpEnd();
286 
287   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle1,
288                                    connection_queue1);
289   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle2,
290                                    connection_queue2);
291   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, le_handle1,
292                                    le_connection_queue1);
293   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, le_handle2,
294                                    le_connection_queue2);
295 
296   std::vector<uint8_t> packet = {0x01, 0x02, 0x03};
297   EnqueueAclUpEnd(queue_up_end1, packet);
298   EnqueueAclUpEnd(le_queue_up_end2, packet);
299   for (uint8_t i = 0; i < 4; i++) {
300     std::vector<uint8_t> packet1 = {0x01, 0x02, 0x03, i};
301     std::vector<uint8_t> packet2 = {0x02, 0x02, 0x03, i};
302     std::vector<uint8_t> le_packet1 = {0x04, 0x05, 0x06, i};
303     std::vector<uint8_t> le_packet2 = {0x05, 0x05, 0x06, i};
304     EnqueueAclUpEnd(queue_up_end1, packet1);
305     EnqueueAclUpEnd(queue_up_end2, packet2);
306     EnqueueAclUpEnd(le_queue_up_end1, le_packet1);
307     EnqueueAclUpEnd(le_queue_up_end2, le_packet2);
308   }
309 
310   packet_future_->wait();
311   VerifyPacket(handle1, packet);
312   VerifyPacket(le_handle2, packet);
313   for (uint8_t i = 0; i < 4; i++) {
314     std::vector<uint8_t> packet1 = {0x01, 0x02, 0x03, i};
315     std::vector<uint8_t> packet2 = {0x02, 0x02, 0x03, i};
316     std::vector<uint8_t> le_packet1 = {0x04, 0x05, 0x06, i};
317     std::vector<uint8_t> le_packet2 = {0x05, 0x05, 0x06, i};
318     VerifyPacket(handle1, packet1);
319     VerifyPacket(handle2, packet2);
320     VerifyPacket(le_handle1, le_packet1);
321     VerifyPacket(le_handle2, le_packet2);
322   }
323 
324   ASSERT_EQ(round_robin_scheduler_->GetCredits(), controller_->max_acl_packet_credits_ - 9);
325   ASSERT_EQ(round_robin_scheduler_->GetLeCredits(), controller_->le_max_acl_packet_credits_ - 9);
326 
327   round_robin_scheduler_->Unregister(handle1);
328   round_robin_scheduler_->Unregister(handle2);
329   round_robin_scheduler_->Unregister(le_handle1);
330   round_robin_scheduler_->Unregister(le_handle2);
331 }
332 
TEST_F(RoundRobinSchedulerTest,send_fragments_without_interval)333 TEST_F(RoundRobinSchedulerTest, send_fragments_without_interval) {
334   uint16_t handle = 0x01;
335   uint16_t le_handle = 0x02;
336   auto connection_queue = std::make_shared<AclConnection::Queue>(10);
337   auto le_connection_queue = std::make_shared<AclConnection::Queue>(10);
338 
339   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
340                                    connection_queue);
341   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, le_handle,
342                                    le_connection_queue);
343 
344   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(5));
345   AclConnection::QueueUpEnd* queue_up_end = connection_queue->GetUpEnd();
346   AclConnection::QueueUpEnd* le_queue_up_end = le_connection_queue->GetUpEnd();
347   std::vector<uint8_t> packet(controller_->hci_mtu_, 0xff);
348   std::vector<uint8_t> packet_part1(controller_->hci_mtu_, 0xff);
349   std::vector<uint8_t> packet_part2 = {0x03, 0x02, 0x01};
350   packet.insert(packet.end(), packet_part2.begin(), packet_part2.end());
351 
352   std::vector<uint8_t> le_packet;
353   std::vector<uint8_t> le_packet_part1;
354   std::vector<uint8_t> le_packet_part2;
355   std::vector<uint8_t> le_packet_part3;
356   for (uint8_t i = 0; i < controller_->le_hci_mtu_; i++) {
357     le_packet.push_back(i);
358     le_packet_part1.push_back(i);
359     le_packet_part2.push_back(i * 2);
360     le_packet_part3.push_back(i * 3);
361   }
362   le_packet.insert(le_packet.end(), le_packet_part2.begin(), le_packet_part2.end());
363   le_packet.insert(le_packet.end(), le_packet_part3.begin(), le_packet_part3.end());
364 
365   EnqueueAclUpEnd(le_queue_up_end, le_packet);
366   EnqueueAclUpEnd(queue_up_end, packet);
367 
368   packet_future_->wait();
369   VerifyPacket(le_handle, le_packet_part1);
370   VerifyPacket(le_handle, le_packet_part2);
371   VerifyPacket(le_handle, le_packet_part3);
372   VerifyPacket(handle, packet_part1);
373   VerifyPacket(handle, packet_part2);
374   ASSERT_EQ(round_robin_scheduler_->GetCredits(), controller_->max_acl_packet_credits_ - 2);
375   ASSERT_EQ(round_robin_scheduler_->GetLeCredits(), controller_->le_max_acl_packet_credits_ - 3);
376 
377   round_robin_scheduler_->Unregister(handle);
378   round_robin_scheduler_->Unregister(le_handle);
379 }
380 
TEST_F(RoundRobinSchedulerTest,receive_le_credit_when_next_fragment_is_classic)381 TEST_F(RoundRobinSchedulerTest, receive_le_credit_when_next_fragment_is_classic) {
382   uint16_t handle = 0x01;
383   uint16_t le_handle = 0x02;
384   auto connection_queue = std::make_shared<AclConnection::Queue>(20);
385   auto le_connection_queue = std::make_shared<AclConnection::Queue>(20);
386 
387   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
388                                    connection_queue);
389   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, le_handle,
390                                    le_connection_queue);
391 
392   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(controller_->le_max_acl_packet_credits_ +
393                                           controller_->max_acl_packet_credits_));
394   AclConnection::QueueUpEnd* queue_up_end = connection_queue->GetUpEnd();
395   AclConnection::QueueUpEnd* le_queue_up_end = le_connection_queue->GetUpEnd();
396   std::vector<uint8_t> huge_packet(2000);
397   std::vector<uint8_t> packet = {0x01, 0x02, 0x03};
398   std::vector<uint8_t> le_packet = {0x04, 0x05, 0x06};
399 
400   // Make le_acl_packet_credits_ = 0;
401   for (uint16_t i = 0; i < controller_->le_max_acl_packet_credits_; i++) {
402     EnqueueAclUpEnd(le_queue_up_end, le_packet);
403   }
404 
405   // Make acl_packet_credits_ = 0 and remain 1 acl fragment in fragments_to_send_
406   for (uint16_t i = 0; i < controller_->max_acl_packet_credits_ - 1; i++) {
407     EnqueueAclUpEnd(queue_up_end, packet);
408   }
409   EnqueueAclUpEnd(queue_up_end, huge_packet);
410 
411   packet_future_->wait();
412 
413   // Trigger start_round_robin
414   controller_->SendCompletedAclPacketsCallback(0x02, 1);
415   std::this_thread::sleep_for(std::chrono::milliseconds(20));
416 
417   ASSERT_EQ(round_robin_scheduler_->GetCredits(), 0);
418   ASSERT_EQ(round_robin_scheduler_->GetLeCredits(), 1);
419 
420   round_robin_scheduler_->Unregister(handle);
421   round_robin_scheduler_->Unregister(le_handle);
422 }
423 
TEST_F(RoundRobinSchedulerTest,unregister_reclaim_credits)424 TEST_F(RoundRobinSchedulerTest, unregister_reclaim_credits) {
425   com::android::bluetooth::flags::provider_->drop_acl_fragment_on_disconnect(true);
426 
427   uint16_t handle = 0x01;
428   auto connection_queue = std::make_shared<AclConnection::Queue>(20);
429   auto new_connection_queue = std::make_shared<AclConnection::Queue>(20);
430 
431   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
432                                    connection_queue);
433 
434   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(controller_->max_acl_packet_credits_));
435 
436   AclConnection::QueueUpEnd* queue_up_end = connection_queue->GetUpEnd();
437 
438   std::vector<uint8_t> huge_packet(2000);
439   std::vector<uint8_t> packet = {0x01, 0x02, 0x03};
440   std::vector<uint8_t> new_packet = {0x04, 0x05, 0x06};
441 
442   // Make acl_packet_credits_ = 0 and remain 1 acl fragment in fragments_to_send_
443   for (uint16_t i = 0; i < controller_->max_acl_packet_credits_ - 1; i++) {
444     EnqueueAclUpEnd(queue_up_end, packet);
445   }
446   EnqueueAclUpEnd(queue_up_end, huge_packet);
447 
448   packet_future_->wait();
449   ASSERT_EQ(round_robin_scheduler_->GetCredits(), 0);
450 
451   // Credits should be reclaimed
452   round_robin_scheduler_->Unregister(handle);
453   ASSERT_EQ(round_robin_scheduler_->GetCredits(), controller_->max_acl_packet_credits_);
454 
455   while (!sent_acl_packets_.empty()) {
456     sent_acl_packets_.pop();
457   }
458 
459   round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle,
460                                    new_connection_queue);
461   ASSERT_NO_FATAL_FAILURE(SetPacketFuture(controller_->max_acl_packet_credits_));
462 
463   AclConnection::QueueUpEnd* new_queue_up_end = new_connection_queue->GetUpEnd();
464   for (uint16_t i = 0; i < controller_->max_acl_packet_credits_; i++) {
465     EnqueueAclUpEnd(new_queue_up_end, new_packet);
466   }
467 
468   packet_future_->wait();
469 
470   // Pending fragments shouldn't be sent
471   for (uint16_t i = 0; i < controller_->max_acl_packet_credits_; i++) {
472     VerifyPacket(handle, new_packet);
473   }
474   round_robin_scheduler_->Unregister(handle);
475 }
476 
477 }  // namespace
478 }  // namespace acl_manager
479 }  // namespace hci
480 }  // namespace bluetooth
481