• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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