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 try_register_dequeue();
65 }
66
GetNextPacket()67 std::unique_ptr<Sender::UpperDequeue> Sender::GetNextPacket() {
68 return data_controller_->GetNextPacket();
69 }
70
GetDataController()71 DataController* Sender::GetDataController() {
72 return data_controller_.get();
73 }
74
try_register_dequeue()75 void Sender::try_register_dequeue() {
76 if (is_dequeue_registered_.exchange(true)) {
77 return;
78 }
79 queue_end_->RegisterDequeue(handler_, common::Bind(&Sender::dequeue_callback, common::Unretained(this)));
80 }
81
82 // From external context
dequeue_callback()83 void Sender::dequeue_callback() {
84 auto packet = queue_end_->TryDequeue();
85 ASSERT(packet != nullptr);
86 handler_->Post(
87 common::BindOnce(&DataController::OnSdu, common::Unretained(data_controller_.get()), std::move(packet)));
88 if (is_dequeue_registered_.exchange(false)) {
89 queue_end_->UnregisterDequeue();
90 }
91 }
92
UpdateClassicConfiguration(classic::internal::ChannelConfigurationState config)93 void Sender::UpdateClassicConfiguration(classic::internal::ChannelConfigurationState config) {
94 auto mode = config.retransmission_and_flow_control_mode_;
95 if (mode == mode_) {
96 return;
97 }
98 if (mode == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) {
99 data_controller_ =
100 std::make_unique<BasicModeDataController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
101 return;
102 }
103 if (mode == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
104 data_controller_ =
105 std::make_unique<ErtmController>(link_, channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
106 RetransmissionAndFlowControlConfigurationOption option = config.local_retransmission_and_flow_control_;
107 option.tx_window_size_ = config.remote_retransmission_and_flow_control_.tx_window_size_;
108 data_controller_->SetRetransmissionAndFlowControlOptions(option);
109 data_controller_->EnableFcs(config.fcs_type_ == FcsType::DEFAULT);
110 return;
111 }
112 }
113
114 } // namespace internal
115 } // namespace l2cap
116 } // namespace bluetooth
117