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( 36 os::Handler* handler, Controller* controller, 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 void Register(ConnectionType connection_type, uint16_t handle, 50 std::shared_ptr<acl_manager::AclConnection::Queue> queue); 51 void Unregister(uint16_t handle); 52 void SetLinkPriority(uint16_t handle, bool high_priority); 53 uint16_t GetCredits(); 54 uint16_t GetLeCredits(); 55 56 private: 57 void start_round_robin(); 58 void buffer_packet(uint16_t acl_handle); 59 void unregister_all_connections(); 60 void send_next_fragment(); 61 std::unique_ptr<AclBuilder> handle_enqueue_next_fragment(); 62 void incoming_acl_credits(uint16_t handle, uint16_t credits); 63 64 os::Handler* handler_ = nullptr; 65 Controller* controller_ = nullptr; 66 std::map<uint16_t, acl_queue_handler> acl_queue_handlers_; 67 common::MultiPriorityQueue<std::pair<ConnectionType, std::unique_ptr<AclBuilder>>, 2> fragments_to_send_; 68 uint16_t max_acl_packet_credits_ = 0; 69 uint16_t acl_packet_credits_ = 0; 70 uint16_t le_max_acl_packet_credits_ = 0; 71 uint16_t le_acl_packet_credits_ = 0; 72 size_t hci_mtu_{0}; 73 size_t le_hci_mtu_{0}; 74 std::atomic_bool enqueue_registered_ = false; 75 common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end_ = nullptr; 76 // first register queue end for the Round-robin schedule 77 std::map<uint16_t, acl_queue_handler>::iterator starting_point_; 78 }; 79 80 } // namespace acl_manager 81 } // namespace hci 82 } // namespace bluetooth 83 84 namespace fmt { 85 template <> 86 struct formatter<bluetooth::hci::acl_manager::RoundRobinScheduler::ConnectionType> 87 : enum_formatter<bluetooth::hci::acl_manager::RoundRobinScheduler::ConnectionType> {}; 88 } // namespace fmt 89