1 /*
2 * Copyright 2019 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 #include <unordered_map>
18
19 #include "common/bind.h"
20 #include "l2cap/internal/basic_mode_channel_data_controller.h"
21 #include "l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h"
22 #include "l2cap/internal/le_credit_based_channel_data_controller.h"
23 #include "l2cap/internal/scheduler.h"
24 #include "l2cap/internal/sender.h"
25 #include "os/handler.h"
26 #include "os/log.h"
27
28 namespace bluetooth {
29 namespace l2cap {
30 namespace internal {
31
Sender(os::Handler * handler,ILink * link,Scheduler * scheduler,std::shared_ptr<ChannelImpl> channel)32 Sender::Sender(os::Handler* handler, ILink* link, Scheduler* scheduler, std::shared_ptr<ChannelImpl> channel)
33 : handler_(handler), link_(link), queue_end_(channel->GetQueueDownEnd()), scheduler_(scheduler),
34 channel_id_(channel->GetCid()), remote_channel_id_(channel->GetRemoteCid()),
35 data_controller_(std::make_unique<BasicModeDataController>(channel_id_, remote_channel_id_, queue_end_, handler_,
36 scheduler_)) {
37 try_register_dequeue();
38 }
39
Sender(os::Handler * handler,ILink * link,Scheduler * scheduler,std::shared_ptr<ChannelImpl> channel,ChannelMode mode)40 Sender::Sender(os::Handler* handler, ILink* link, Scheduler* scheduler, std::shared_ptr<ChannelImpl> channel,
41 ChannelMode mode)
42 : handler_(handler), link_(link), queue_end_(channel->GetQueueDownEnd()), scheduler_(scheduler),
43 channel_id_(channel->GetCid()), remote_channel_id_(channel->GetRemoteCid()) {
44 if (mode == ChannelMode::BASIC) {
45 data_controller_ =
46 std::make_unique<BasicModeDataController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
47 } else if (mode == ChannelMode::ERTM) {
48 data_controller_ =
49 std::make_unique<ErtmController>(link_, channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
50 } else if (mode == ChannelMode::LE_CREDIT_BASED) {
51 data_controller_ = std::make_unique<LeCreditBasedDataController>(link_, channel_id_, remote_channel_id_, queue_end_,
52 handler_, scheduler_);
53 }
54 try_register_dequeue();
55 }
56
~Sender()57 Sender::~Sender() {
58 if (is_dequeue_registered_.exchange(false)) {
59 queue_end_->UnregisterDequeue();
60 }
61 }
62
OnPacketSent()63 void Sender::OnPacketSent() {
64 link_->OnPendingPacketChange(channel_id_, false);
65 try_register_dequeue();
66 }
67
GetNextPacket()68 std::unique_ptr<Sender::UpperDequeue> Sender::GetNextPacket() {
69 return data_controller_->GetNextPacket();
70 }
71
GetDataController()72 DataController* Sender::GetDataController() {
73 return data_controller_.get();
74 }
75
try_register_dequeue()76 void Sender::try_register_dequeue() {
77 if (is_dequeue_registered_.exchange(true)) {
78 return;
79 }
80 queue_end_->RegisterDequeue(handler_, common::Bind(&Sender::dequeue_callback, common::Unretained(this)));
81 }
82
83 // From external context
dequeue_callback()84 void Sender::dequeue_callback() {
85 auto packet = queue_end_->TryDequeue();
86 ASSERT(packet != nullptr);
87 handler_->Post(
88 common::BindOnce(&DataController::OnSdu, common::Unretained(data_controller_.get()), std::move(packet)));
89 if (is_dequeue_registered_.exchange(false)) {
90 queue_end_->UnregisterDequeue();
91 }
92 link_->OnPendingPacketChange(channel_id_, true);
93 }
94
UpdateClassicConfiguration(classic::internal::ChannelConfigurationState config)95 void Sender::UpdateClassicConfiguration(classic::internal::ChannelConfigurationState config) {
96 auto mode = config.retransmission_and_flow_control_mode_;
97 if (mode == mode_) {
98 return;
99 }
100 if (mode == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) {
101 data_controller_ =
102 std::make_unique<BasicModeDataController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
103 return;
104 }
105 if (mode == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
106 data_controller_ =
107 std::make_unique<ErtmController>(link_, channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
108 RetransmissionAndFlowControlConfigurationOption option = config.local_retransmission_and_flow_control_;
109 option.tx_window_size_ = config.remote_retransmission_and_flow_control_.tx_window_size_;
110 data_controller_->SetRetransmissionAndFlowControlOptions(option);
111 data_controller_->EnableFcs(config.fcs_type_ == FcsType::DEFAULT);
112 return;
113 }
114 }
115
116 } // namespace internal
117 } // namespace l2cap
118 } // namespace bluetooth
119