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 #pragma once 18 19 #include <bluetooth/log.h> 20 #include <stdint.h> 21 22 #include "common/bidi_queue.h" 23 #include "common/multi_priority_queue.h" 24 #include "hci/acl_manager/acl_connection.h" 25 #include "hci/controller.h" 26 #include "hci/hci_packets.h" 27 #include "os/handler.h" 28 29 namespace bluetooth { 30 namespace hci { 31 namespace acl_manager { 32 33 class RoundRobinScheduler { 34 public: 35 RoundRobinScheduler(os::Handler* handler, Controller* controller, 36 common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end); 37 ~RoundRobinScheduler(); 38 39 enum ConnectionType { CLASSIC, LE }; 40 41 struct acl_queue_handler { 42 ConnectionType connection_type_; 43 std::shared_ptr<acl_manager::AclConnection::Queue> queue_; 44 bool dequeue_is_registered_ = false; 45 uint16_t number_of_sent_packets_ = 0; // Track credits 46 bool high_priority_ = false; // For A2dp use 47 }; 48 49 struct packet_fragment { 50 ConnectionType connection_type_; 51 uint16_t handle_; 52 int priority_; 53 std::unique_ptr<AclBuilder> packet_; 54 }; 55 56 void Register(ConnectionType connection_type, uint16_t handle, 57 std::shared_ptr<acl_manager::AclConnection::Queue> queue); 58 void Unregister(uint16_t handle); 59 void SetLinkPriority(uint16_t handle, bool high_priority); 60 uint16_t GetCredits(); 61 uint16_t GetLeCredits(); 62 63 private: 64 void start_round_robin(); 65 void buffer_packet(uint16_t acl_handle); 66 void drop_packet_fragments(uint16_t acl_handle); 67 void unregister_all_connections(); 68 void send_next_fragment(); 69 std::unique_ptr<AclBuilder> handle_enqueue_next_fragment(); 70 void incoming_acl_credits(uint16_t handle, uint16_t credits); 71 72 os::Handler* handler_ = nullptr; 73 Controller* controller_ = nullptr; 74 std::map<uint16_t, acl_queue_handler> acl_queue_handlers_; 75 common::MultiPriorityQueue<packet_fragment, 2> fragments_to_send_; 76 uint16_t max_acl_packet_credits_ = 0; 77 uint16_t acl_packet_credits_ = 0; 78 uint16_t le_max_acl_packet_credits_ = 0; 79 uint16_t le_acl_packet_credits_ = 0; 80 size_t hci_mtu_{0}; 81 size_t le_hci_mtu_{0}; 82 std::atomic_bool enqueue_registered_ = false; 83 common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end_ = nullptr; 84 // first register queue end for the Round-robin schedule 85 std::map<uint16_t, acl_queue_handler>::iterator starting_point_; 86 }; 87 88 } // namespace acl_manager 89 } // namespace hci 90 } // namespace bluetooth 91 92 namespace std { 93 template <> 94 struct formatter<bluetooth::hci::acl_manager::RoundRobinScheduler::ConnectionType> 95 : enum_formatter<bluetooth::hci::acl_manager::RoundRobinScheduler::ConnectionType> {}; 96 } // namespace std 97