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