Loading system/gd/l2cap/classic/internal/link.h +2 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,8 @@ class Link : public l2cap::internal::ILink { return GetDevice().ToString(); } void SendLeCredit(Cid local_cid, uint16_t credit) override {} private: os::Handler* l2cap_handler_; l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_}; Loading system/gd/l2cap/internal/ilink.h +4 −1 Original line number Diff line number Diff line Loading @@ -28,9 +28,12 @@ namespace internal { */ class ILink { public: virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) = 0; virtual ~ILink() = default; virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) = 0; virtual hci::AddressWithType GetDevice() = 0; // To be used by LE credit based channel data controller over LE link virtual void SendLeCredit(Cid local_cid, uint16_t credit) = 0; }; } // namespace internal } // namespace l2cap Loading system/gd/l2cap/internal/ilink_mock.h +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ class MockILink : public ILink { public: MOCK_METHOD(hci::AddressWithType, GetDevice, (), (override)); MOCK_METHOD(void, SendDisconnectionRequest, (Cid, Cid), (override)); MOCK_METHOD(void, SendLeCredit, (Cid, uint16_t), (override)); }; } // namespace testing Loading system/gd/l2cap/internal/le_credit_based_channel_data_controller.cc +28 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "l2cap/internal/le_credit_based_channel_data_controller.h" #include "l2cap/l2cap_packets.h" #include "l2cap/le/internal/link.h" #include "packet/fragmenting_inserter.h" #include "packet/raw_builder.h" Loading @@ -27,8 +28,8 @@ namespace internal { LeCreditBasedDataController::LeCreditBasedDataController(ILink* link, Cid cid, Cid remote_cid, UpperQueueDownEnd* channel_queue_end, os::Handler* handler, Scheduler* scheduler) : cid_(cid), remote_cid_(remote_cid), enqueue_buffer_(channel_queue_end), handler_(handler), scheduler_(scheduler) { } : cid_(cid), remote_cid_(remote_cid), enqueue_buffer_(channel_queue_end), handler_(handler), scheduler_(scheduler), link_(link) {} void LeCreditBasedDataController::OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) { auto sdu_size = sdu->size(); Loading @@ -51,7 +52,16 @@ void LeCreditBasedDataController::OnSdu(std::unique_ptr<packet::BasePacketBuilde builder = BasicFrameBuilder::Create(remote_cid_, std::move(segments[i])); pdu_queue_.emplace(std::move(builder)); } if (credits_ >= segments.size()) { scheduler_->OnPacketsReady(cid_, segments.size()); credits_ -= segments.size(); } else if (credits_ > 0) { scheduler_->OnPacketsReady(cid_, credits_); pending_frames_count_ += (segments.size() - credits_); credits_ = 0; } else { pending_frames_count_ += segments.size(); } } void LeCreditBasedDataController::OnPdu(packet::PacketView<true> pdu) { Loading Loading @@ -85,8 +95,10 @@ void LeCreditBasedDataController::OnPdu(packet::PacketView<true> pdu) { LOG_WARN("Received larger SDU size than expected"); reassembly_stage_ = PacketViewForReassembly(std::make_shared<std::vector<uint8_t>>()); remaining_sdu_continuation_packet_size_ = 0; // TODO: Close channel link_->SendDisconnectionRequest(cid_, remote_cid_); } // TODO: Improve the logic by sending credit only after user dequeued the SDU link_->SendLeCredit(cid_, 1); } std::unique_ptr<packet::BasePacketBuilder> LeCreditBasedDataController::GetNextPacket() { Loading @@ -105,7 +117,18 @@ void LeCreditBasedDataController::SetMps(uint16_t mps) { void LeCreditBasedDataController::OnCredit(uint16_t credits) { int total_credits = credits_ + credits; credits_ = total_credits > 0xffff ? 0xffff : total_credits; if (total_credits > 0xffff) { link_->SendDisconnectionRequest(cid_, remote_cid_); } credits_ = total_credits; if (pending_frames_count_ > 0 && credits_ >= pending_frames_count_) { scheduler_->OnPacketsReady(cid_, pending_frames_count_); credits_ -= pending_frames_count_; } else if (pending_frames_count_ > 0) { scheduler_->OnPacketsReady(cid_, credits_); pending_frames_count_ -= credits_; credits_ = 0; } } } // namespace internal Loading system/gd/l2cap/internal/le_credit_based_channel_data_controller.h +2 −0 Original line number Diff line number Diff line Loading @@ -65,9 +65,11 @@ class LeCreditBasedDataController : public DataController { os::Handler* handler_; std::queue<std::unique_ptr<packet::BasePacketBuilder>> pdu_queue_; Scheduler* scheduler_; ILink* link_; Mtu mtu_ = 512; uint16_t mps_ = 251; uint16_t credits_ = 0; uint16_t pending_frames_count_ = 0; class PacketViewForReassembly : public packet::PacketView<kLittleEndian> { public: Loading Loading
system/gd/l2cap/classic/internal/link.h +2 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,8 @@ class Link : public l2cap::internal::ILink { return GetDevice().ToString(); } void SendLeCredit(Cid local_cid, uint16_t credit) override {} private: os::Handler* l2cap_handler_; l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_}; Loading
system/gd/l2cap/internal/ilink.h +4 −1 Original line number Diff line number Diff line Loading @@ -28,9 +28,12 @@ namespace internal { */ class ILink { public: virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) = 0; virtual ~ILink() = default; virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) = 0; virtual hci::AddressWithType GetDevice() = 0; // To be used by LE credit based channel data controller over LE link virtual void SendLeCredit(Cid local_cid, uint16_t credit) = 0; }; } // namespace internal } // namespace l2cap Loading
system/gd/l2cap/internal/ilink_mock.h +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ class MockILink : public ILink { public: MOCK_METHOD(hci::AddressWithType, GetDevice, (), (override)); MOCK_METHOD(void, SendDisconnectionRequest, (Cid, Cid), (override)); MOCK_METHOD(void, SendLeCredit, (Cid, uint16_t), (override)); }; } // namespace testing Loading
system/gd/l2cap/internal/le_credit_based_channel_data_controller.cc +28 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "l2cap/internal/le_credit_based_channel_data_controller.h" #include "l2cap/l2cap_packets.h" #include "l2cap/le/internal/link.h" #include "packet/fragmenting_inserter.h" #include "packet/raw_builder.h" Loading @@ -27,8 +28,8 @@ namespace internal { LeCreditBasedDataController::LeCreditBasedDataController(ILink* link, Cid cid, Cid remote_cid, UpperQueueDownEnd* channel_queue_end, os::Handler* handler, Scheduler* scheduler) : cid_(cid), remote_cid_(remote_cid), enqueue_buffer_(channel_queue_end), handler_(handler), scheduler_(scheduler) { } : cid_(cid), remote_cid_(remote_cid), enqueue_buffer_(channel_queue_end), handler_(handler), scheduler_(scheduler), link_(link) {} void LeCreditBasedDataController::OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) { auto sdu_size = sdu->size(); Loading @@ -51,7 +52,16 @@ void LeCreditBasedDataController::OnSdu(std::unique_ptr<packet::BasePacketBuilde builder = BasicFrameBuilder::Create(remote_cid_, std::move(segments[i])); pdu_queue_.emplace(std::move(builder)); } if (credits_ >= segments.size()) { scheduler_->OnPacketsReady(cid_, segments.size()); credits_ -= segments.size(); } else if (credits_ > 0) { scheduler_->OnPacketsReady(cid_, credits_); pending_frames_count_ += (segments.size() - credits_); credits_ = 0; } else { pending_frames_count_ += segments.size(); } } void LeCreditBasedDataController::OnPdu(packet::PacketView<true> pdu) { Loading Loading @@ -85,8 +95,10 @@ void LeCreditBasedDataController::OnPdu(packet::PacketView<true> pdu) { LOG_WARN("Received larger SDU size than expected"); reassembly_stage_ = PacketViewForReassembly(std::make_shared<std::vector<uint8_t>>()); remaining_sdu_continuation_packet_size_ = 0; // TODO: Close channel link_->SendDisconnectionRequest(cid_, remote_cid_); } // TODO: Improve the logic by sending credit only after user dequeued the SDU link_->SendLeCredit(cid_, 1); } std::unique_ptr<packet::BasePacketBuilder> LeCreditBasedDataController::GetNextPacket() { Loading @@ -105,7 +117,18 @@ void LeCreditBasedDataController::SetMps(uint16_t mps) { void LeCreditBasedDataController::OnCredit(uint16_t credits) { int total_credits = credits_ + credits; credits_ = total_credits > 0xffff ? 0xffff : total_credits; if (total_credits > 0xffff) { link_->SendDisconnectionRequest(cid_, remote_cid_); } credits_ = total_credits; if (pending_frames_count_ > 0 && credits_ >= pending_frames_count_) { scheduler_->OnPacketsReady(cid_, pending_frames_count_); credits_ -= pending_frames_count_; } else if (pending_frames_count_ > 0) { scheduler_->OnPacketsReady(cid_, credits_); pending_frames_count_ -= credits_; credits_ = 0; } } } // namespace internal Loading
system/gd/l2cap/internal/le_credit_based_channel_data_controller.h +2 −0 Original line number Diff line number Diff line Loading @@ -65,9 +65,11 @@ class LeCreditBasedDataController : public DataController { os::Handler* handler_; std::queue<std::unique_ptr<packet::BasePacketBuilder>> pdu_queue_; Scheduler* scheduler_; ILink* link_; Mtu mtu_ = 512; uint16_t mps_ = 251; uint16_t credits_ = 0; uint16_t pending_frames_count_ = 0; class PacketViewForReassembly : public packet::PacketView<kLittleEndian> { public: Loading