*/
virtual void SetChannelTxPriority(Cid cid, bool high_priority) {}
+ /**
+ * Called by data controller to indicate that a channel is closed and packets should be dropped
+ */
+ virtual void RemoveChannel(Cid cid) {}
+
virtual ~Scheduler() = default;
};
}
}
+void Fifo::RemoveChannel(Cid cid) {
+ for (int i = 0; i < next_to_dequeue_and_num_packets.size(); i++) {
+ auto& channel_id_and_number_packets = next_to_dequeue_and_num_packets.front();
+ if (channel_id_and_number_packets.second != cid) {
+ next_to_dequeue_and_num_packets.push(channel_id_and_number_packets);
+ }
+ next_to_dequeue_and_num_packets.pop();
+ }
+ if (next_to_dequeue_and_num_packets.empty() && link_queue_enqueue_registered_.exchange(false)) {
+ link_queue_up_end_->UnregisterEnqueue();
+ }
+}
+
// Invoked from some external Queue Reactable context
std::unique_ptr<Fifo::UpperDequeue> Fifo::link_queue_enqueue_callback() {
ASSERT(!next_to_dequeue_and_num_packets.empty());
enqueue_.enqueued.pop();
}
+TEST_F(L2capSchedulerFifoTest, remove_channel) {
+ auto frame = BasicFrameBuilder::Create(1, CreateSdu({'a', 'b', 'c'}));
+ data_controller_1_.next_packets.push(std::move(frame));
+ frame = BasicFrameBuilder::Create(2, CreateSdu({'d', 'e', 'f'}));
+ data_controller_2_.next_packets.push(std::move(frame));
+
+ EXPECT_CALL(*mock_data_pipeline_manager_, GetDataController(1)).WillRepeatedly(Return(&data_controller_1_));
+ EXPECT_CALL(*mock_data_pipeline_manager_, GetDataController(2)).WillRepeatedly(Return(&data_controller_2_));
+ EXPECT_CALL(*mock_data_pipeline_manager_, OnPacketSent(2));
+ fifo_->OnPacketsReady(1, 1);
+ fifo_->OnPacketsReady(2, 1);
+ fifo_->RemoveChannel(1);
+ enqueue_.run_enqueue(1);
+ auto packet1 = std::move(enqueue_.enqueued.front());
+ auto packet_view = GetPacketView(std::move(packet1));
+ auto basic_frame_view = BasicFrameView::Create(packet_view);
+ ASSERT_TRUE(basic_frame_view.IsValid());
+ ASSERT_EQ(basic_frame_view.GetChannelId(), 2);
+ auto payload = basic_frame_view.GetPayload();
+ ASSERT_EQ(std::string(payload.begin(), payload.end()), "def");
+ enqueue_.enqueued.pop();
+}
+
} // namespace
} // namespace internal
} // namespace l2cap