next_to_dequeue_.push(priority);
}
+ // Push the item with specified priority
+ void push(T&& t, int priority = 0) {
+ queues_[priority].push(std::forward<T>(t));
+ next_to_dequeue_.push(priority);
+ }
+
// Pop the item in the front
void pop() {
queues_[next_to_dequeue_.top()].pop();
pimpl_->classic_impl_->HACK_SetScoDisconnectCallback(callback);
}
+void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) {
+ CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority);
+}
+
void AclManager::ListDependencies(ModuleList* list) {
list->add<HciLayer>();
list->add<Controller>();
namespace shim {
class Btm;
void L2CA_UseLegacySecurityModule();
+bool L2CA_SetAclPriority(uint16_t, bool);
}
namespace hci {
class AclManager : public Module {
friend class bluetooth::shim::Btm;
friend void bluetooth::shim::L2CA_UseLegacySecurityModule();
+ friend bool bluetooth::shim::L2CA_SetAclPriority(uint16_t, bool);
public:
AclManager();
// Hack for the shim to get SCO disconnect callback. Shim needs to post to their handler!
virtual void HACK_SetScoDisconnectCallback(std::function<void(uint16_t /* handle */, uint8_t /* reason */)>);
+ virtual void HACK_SetAclTxPriority(uint8_t handle, bool high_priority);
+
struct impl;
std::unique_ptr<impl> pimpl_;
starting_point_ = acl_queue_handlers_.begin();
}
+void RoundRobinScheduler::SetLinkPriority(uint16_t handle, bool high_priority) {
+ auto acl_queue_handler = acl_queue_handlers_.find(handle);
+ if (acl_queue_handler == acl_queue_handlers_.end()) {
+ LOG_WARN("handle %d is invalid", handle);
+ return;
+ }
+ acl_queue_handler->second.high_priority_ = high_priority;
+}
+
uint16_t RoundRobinScheduler::GetCredits() {
return acl_packet_credits_;
}
PacketBoundaryFlag packet_boundary_flag =
(connection_type == ConnectionType::CLASSIC ? PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE
: PacketBoundaryFlag::FIRST_NON_AUTOMATICALLY_FLUSHABLE);
+ int acl_priority = acl_queue_handler->second.high_priority_ ? 1 : 0;
if (packet->size() <= mtu) {
- fragments_to_send_.push(std::make_pair(
- connection_type, AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(packet))));
+ fragments_to_send_.push(
+ std::make_pair(
+ connection_type, AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(packet))),
+ acl_priority);
} else {
auto fragments = AclFragmenter(mtu, std::move(packet)).GetFragments();
for (size_t i = 0; i < fragments.size(); i++) {
- fragments_to_send_.push(std::make_pair(
- connection_type, AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(fragments[i]))));
+ fragments_to_send_.push(
+ std::make_pair(
+ connection_type,
+ AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, std::move(fragments[i]))),
+ acl_priority);
packet_boundary_flag = PacketBoundaryFlag::CONTINUING_FRAGMENT;
}
}
#include <stdint.h>
#include "common/bidi_queue.h"
+#include "common/multi_priority_queue.h"
#include "hci/acl_manager.h"
#include "hci/controller.h"
#include "hci/hci_packets.h"
std::shared_ptr<acl_manager::AclConnection::Queue> queue_;
bool dequeue_is_registered_ = false;
uint16_t number_of_sent_packets_ = 0; // Track credits
+ bool high_priority_ = false; // For A2dp use
};
void Register(ConnectionType connection_type, uint16_t handle,
std::shared_ptr<acl_manager::AclConnection::Queue> queue);
void Unregister(uint16_t handle);
+ void SetLinkPriority(uint16_t handle, bool high_priority);
uint16_t GetCredits();
uint16_t GetLeCredits();
os::Handler* handler_ = nullptr;
Controller* controller_ = nullptr;
std::map<uint16_t, acl_queue_handler> acl_queue_handlers_;
- std::queue<std::pair<ConnectionType, std::unique_ptr<AclBuilder>>> fragments_to_send_;
+ common::MultiPriorityQueue<std::pair<ConnectionType, std::unique_ptr<AclBuilder>>, 2> fragments_to_send_;
uint16_t max_acl_packet_credits_ = 0;
uint16_t acl_packet_credits_ = 0;
uint16_t le_max_acl_packet_credits_ = 0;
}
}
+bool L2CA_SetAclPriority(uint16_t handle, bool high_priority) {
+ GetAclManager()->HACK_SetAclTxPriority(handle, high_priority);
+ return true;
+}
+
bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) {
- LOG_INFO("UNIMPLEMENTED %s", __func__);
- return false;
+ uint16_t handle = security_listener_shim_.address_to_handle_[bd_addr];
+ return L2CA_SetAclPriority(handle, priority == L2CAP_PRIORITY_HIGH);
}
bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,