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