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 "l2cap/classic/internal/signalling_manager.h"
18 
19 #include <chrono>
20 
21 #include "common/bind.h"
22 #include "l2cap/classic/internal/channel_configuration_state.h"
23 #include "l2cap/classic/internal/link.h"
24 #include "l2cap/internal/data_pipeline_manager.h"
25 #include "l2cap/l2cap_packets.h"
26 #include "os/log.h"
27 #include "packet/raw_builder.h"
28 
29 namespace bluetooth {
30 namespace l2cap {
31 namespace classic {
32 namespace internal {
33 static constexpr auto kTimeout = std::chrono::seconds(3);
34 
GetCommandsFromPacketView(PacketView<kLittleEndian> packet)35 static std::vector<ControlView> GetCommandsFromPacketView(PacketView<kLittleEndian> packet) {
36   size_t curr = 0;
37   size_t end = packet.size();
38   std::vector<ControlView> result;
39   while (curr < end) {
40     auto sub_view = packet.GetLittleEndianSubview(curr, end);
41     auto control = ControlView::Create(sub_view);
42     if (!control.IsValid()) {
43       return {};
44     }
45     result.push_back(control);
46     curr += 1 + 1 + 2 + control.GetPayload().size();
47   }
48   return result;
49 }
50 
ClassicSignallingManager(os::Handler * handler,Link * link,l2cap::internal::DataPipelineManager * data_pipeline_manager,DynamicChannelServiceManagerImpl * dynamic_service_manager,l2cap::internal::DynamicChannelAllocator * channel_allocator,FixedChannelServiceManagerImpl * fixed_service_manager)51 ClassicSignallingManager::ClassicSignallingManager(os::Handler* handler, Link* link,
52                                                    l2cap::internal::DataPipelineManager* data_pipeline_manager,
53                                                    DynamicChannelServiceManagerImpl* dynamic_service_manager,
54                                                    l2cap::internal::DynamicChannelAllocator* channel_allocator,
55                                                    FixedChannelServiceManagerImpl* fixed_service_manager)
56     : handler_(handler), link_(link), data_pipeline_manager_(data_pipeline_manager),
57       dynamic_service_manager_(dynamic_service_manager), channel_allocator_(channel_allocator),
58       fixed_service_manager_(fixed_service_manager), alarm_(handler) {
59   ASSERT(handler_ != nullptr);
60   ASSERT(link_ != nullptr);
61   signalling_channel_ = link_->AllocateFixedChannel(kClassicSignallingCid);
62   signalling_channel_->GetQueueUpEnd()->RegisterDequeue(
63       handler_, common::Bind(&ClassicSignallingManager::on_incoming_packet, common::Unretained(this)));
64   enqueue_buffer_ =
65       std::make_unique<os::EnqueueBuffer<packet::BasePacketBuilder>>(signalling_channel_->GetQueueUpEnd());
66 }
67 
~ClassicSignallingManager()68 ClassicSignallingManager::~ClassicSignallingManager() {
69   alarm_.Cancel();
70   signalling_channel_->GetQueueUpEnd()->UnregisterDequeue();
71   signalling_channel_ = nullptr;
72   enqueue_buffer_->Clear();
73   enqueue_buffer_.reset();
74 }
75 
OnCommandReject(CommandRejectView command_reject_view)76 void ClassicSignallingManager::OnCommandReject(CommandRejectView command_reject_view) {
77   if (command_just_sent_.signal_id_ != command_reject_view.GetIdentifier()) {
78     LOG_WARN("Unexpected command reject: no pending request");
79     return;
80   }
81   if (command_just_sent_.command_code_ == CommandCode::INFORMATION_REQUEST &&
82       command_just_sent_.info_type_ == InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED) {
83     link_->OnRemoteExtendedFeatureReceived(false, false);
84   }
85   alarm_.Cancel();
86   handle_send_next_command();
87 
88   LOG_INFO("Command rejected");
89 }
90 
SendConnectionRequest(Psm psm,Cid local_cid)91 void ClassicSignallingManager::SendConnectionRequest(Psm psm, Cid local_cid) {
92   dynamic_service_manager_->GetSecurityEnforcementInterface()->Enforce(
93       link_->GetDevice(),
94       dynamic_service_manager_->GetService(psm)->GetSecurityPolicy(),
95       handler_->BindOnceOn(this, &ClassicSignallingManager::on_security_result_for_outgoing, psm, local_cid));
96 }
97 
on_security_result_for_outgoing(Psm psm,Cid local_cid,bool result)98 void ClassicSignallingManager::on_security_result_for_outgoing(Psm psm, Cid local_cid, bool result) {
99   if (enqueue_buffer_.get() == nullptr) {
100     LOG_ERROR("Got security result callback after deletion");
101     return;
102   }
103   if (!result) {
104     LOG_WARN("Security requirement can't be satisfied. Dropping connection request");
105     DynamicChannelManager::ConnectionResult connection_result{
106         .connection_result_code = DynamicChannelManager::ConnectionResultCode::FAIL_SECURITY_BLOCK,
107         .hci_error = hci::ErrorCode::SUCCESS,
108         .l2cap_connection_response_result = ConnectionResponseResult::NO_RESOURCES_AVAILABLE,
109     };
110     link_->OnOutgoingConnectionRequestFail(local_cid, connection_result);
111     return;
112   }
113 
114   PendingCommand pending_command = {next_signal_id_, CommandCode::CONNECTION_REQUEST, psm, local_cid, {}, {}, {}};
115   next_signal_id_++;
116   pending_commands_.push(std::move(pending_command));
117   if (command_just_sent_.signal_id_ == kInvalidSignalId) {
118     handle_send_next_command();
119   }
120 }
121 
send_configuration_request(Cid remote_cid,std::vector<std::unique_ptr<ConfigurationOption>> config)122 void ClassicSignallingManager::send_configuration_request(Cid remote_cid,
123                                                           std::vector<std::unique_ptr<ConfigurationOption>> config) {
124   PendingCommand pending_command = {next_signal_id_,  CommandCode::CONFIGURATION_REQUEST, {}, {}, remote_cid, {},
125                                     std::move(config)};
126   next_signal_id_++;
127   pending_commands_.push(std::move(pending_command));
128   if (command_just_sent_.signal_id_ == kInvalidSignalId) {
129     handle_send_next_command();
130   }
131 }
132 
SendDisconnectionRequest(Cid local_cid,Cid remote_cid)133 void ClassicSignallingManager::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) {
134   PendingCommand pending_command = {
135       next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}, {}};
136   next_signal_id_++;
137   pending_commands_.push(std::move(pending_command));
138   if (command_just_sent_.signal_id_ == kInvalidSignalId) {
139     handle_send_next_command();
140   }
141 }
142 
SendInformationRequest(InformationRequestInfoType type)143 void ClassicSignallingManager::SendInformationRequest(InformationRequestInfoType type) {
144   PendingCommand pending_command = {next_signal_id_, CommandCode::INFORMATION_REQUEST, {}, {}, {}, type, {}};
145   next_signal_id_++;
146   pending_commands_.push(std::move(pending_command));
147   if (command_just_sent_.signal_id_ == kInvalidSignalId) {
148     handle_send_next_command();
149   }
150 }
151 
SendEchoRequest(std::unique_ptr<packet::RawBuilder> payload)152 void ClassicSignallingManager::SendEchoRequest(std::unique_ptr<packet::RawBuilder> payload) {
153   LOG_WARN("Not supported");
154 }
155 
CancelAlarm()156 void ClassicSignallingManager::CancelAlarm() {
157   alarm_.Cancel();
158 }
159 
OnConnectionRequest(SignalId signal_id,Psm psm,Cid remote_cid)160 void ClassicSignallingManager::OnConnectionRequest(SignalId signal_id, Psm psm, Cid remote_cid) {
161   if (!IsPsmValid(psm)) {
162     LOG_WARN("Invalid psm received from remote psm:%d remote_cid:%d", psm, remote_cid);
163     send_connection_response(signal_id, remote_cid, kInvalidCid, ConnectionResponseResult::PSM_NOT_SUPPORTED,
164                              ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
165     return;
166   }
167 
168   if (remote_cid == kInvalidCid) {
169     LOG_WARN("Invalid remote cid received from remote psm:%d remote_cid:%d", psm, remote_cid);
170     send_connection_response(signal_id, remote_cid, kInvalidCid, ConnectionResponseResult::INVALID_CID,
171                              ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
172     return;
173   }
174   /* TODO(zachoverflow): add back in with policy
175   if (channel_allocator_->IsPsmUsed(psm)) {
176     LOG_WARN("Psm already exists");
177     send_connection_response(signal_id, remote_cid, kInvalidCid, ConnectionResponseResult::PSM_NOT_SUPPORTED,
178                              ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
179     return;
180   }
181   */
182 
183   if (!dynamic_service_manager_->IsServiceRegistered(psm)) {
184     LOG_INFO("Service for this psm (%d) is not registered", psm);
185     send_connection_response(signal_id, remote_cid, kInvalidCid, ConnectionResponseResult::PSM_NOT_SUPPORTED,
186                              ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
187     return;
188   }
189 
190   dynamic_service_manager_->GetSecurityEnforcementInterface()->Enforce(
191       link_->GetDevice(),
192       dynamic_service_manager_->GetService(psm)->GetSecurityPolicy(),
193       handler_->BindOnceOn(
194           this, &ClassicSignallingManager::on_security_result_for_incoming, psm, remote_cid, signal_id));
195 }
196 
on_security_result_for_incoming(Psm psm,Cid remote_cid,SignalId signal_id,bool result)197 void ClassicSignallingManager::on_security_result_for_incoming(
198     Psm psm, Cid remote_cid, SignalId signal_id, bool result) {
199   if (enqueue_buffer_.get() == nullptr) {
200     LOG_ERROR("Got security result callback after deletion");
201     return;
202   }
203   if (!result) {
204     send_connection_response(
205         signal_id,
206         remote_cid,
207         0,
208         ConnectionResponseResult::SECURITY_BLOCK,
209         ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
210     DynamicChannelManager::ConnectionResult connection_result{
211         .connection_result_code = DynamicChannelManager::ConnectionResultCode::FAIL_SECURITY_BLOCK,
212         .hci_error = hci::ErrorCode::SUCCESS,
213         .l2cap_connection_response_result = ConnectionResponseResult::NO_RESOURCES_AVAILABLE,
214     };
215     link_->OnOutgoingConnectionRequestFail(0, connection_result);
216   }
217 
218   auto new_channel = link_->AllocateDynamicChannel(psm, remote_cid);
219   if (new_channel == nullptr) {
220     LOG_WARN("Can't allocate dynamic channel");
221     return;
222   }
223   send_connection_response(
224       signal_id,
225       remote_cid,
226       new_channel->GetCid(),
227       ConnectionResponseResult::SUCCESS,
228       ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
229 
230   link_->SendInitialConfigRequestOrQueue(new_channel->GetCid());
231 }
232 
OnConnectionResponse(SignalId signal_id,Cid remote_cid,Cid cid,ConnectionResponseResult result,ConnectionResponseStatus status)233 void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remote_cid, Cid cid,
234                                                     ConnectionResponseResult result, ConnectionResponseStatus status) {
235   if (command_just_sent_.signal_id_ != signal_id ||
236       command_just_sent_.command_code_ != CommandCode::CONNECTION_REQUEST) {
237     LOG_WARN("Unexpected response: no pending request. Expected signal id %d type %s, got %d",
238              command_just_sent_.signal_id_.Value(), CommandCodeText(command_just_sent_.command_code_).data(),
239              signal_id.Value());
240     return;
241   }
242   if (command_just_sent_.source_cid_ != cid) {
243     LOG_WARN("SCID doesn't match: expected %d, received %d", command_just_sent_.source_cid_, cid);
244     handle_send_next_command();
245     return;
246   }
247   if (result == ConnectionResponseResult::PENDING) {
248     alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
249                     kTimeout);
250     return;
251   }
252 
253   command_just_sent_.signal_id_ = kInvalidSignalId;
254   alarm_.Cancel();
255   if (result != ConnectionResponseResult::SUCCESS) {
256     DynamicChannelManager::ConnectionResult connection_result{
257         .connection_result_code = DynamicChannelManager::ConnectionResultCode::FAIL_L2CAP_ERROR,
258         .hci_error = hci::ErrorCode::SUCCESS,
259         .l2cap_connection_response_result = result,
260     };
261     link_->OnOutgoingConnectionRequestFail(cid, connection_result);
262     handle_send_next_command();
263     return;
264   }
265   Psm pending_psm = command_just_sent_.psm_;
266   auto new_channel = link_->AllocateReservedDynamicChannel(cid, pending_psm, remote_cid);
267   if (new_channel == nullptr) {
268     LOG_WARN("Can't allocate dynamic channel");
269     DynamicChannelManager::ConnectionResult connection_result{
270         .connection_result_code = DynamicChannelManager::ConnectionResultCode::FAIL_L2CAP_ERROR,
271         .hci_error = hci::ErrorCode::SUCCESS,
272         .l2cap_connection_response_result = ConnectionResponseResult::NO_RESOURCES_AVAILABLE,
273     };
274     link_->OnOutgoingConnectionRequestFail(cid, connection_result);
275     handle_send_next_command();
276     return;
277   }
278 
279   link_->SendInitialConfigRequestOrQueue(cid);
280 }
281 
OnConfigurationRequest(SignalId signal_id,Cid cid,Continuation is_continuation,std::vector<std::unique_ptr<ConfigurationOption>> options)282 void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid cid, Continuation is_continuation,
283                                                       std::vector<std::unique_ptr<ConfigurationOption>> options) {
284   auto channel = channel_allocator_->FindChannelByCid(cid);
285   if (channel == nullptr) {
286     LOG_WARN("Configuration request for an unknown channel");
287     return;
288   }
289 
290   auto& configuration_state = channel_configuration_[cid];
291   std::vector<std::unique_ptr<ConfigurationOption>> rsp_options;
292   ConfigurationResponseResult result = ConfigurationResponseResult::SUCCESS;
293   auto remote_rfc_mode = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
294 
295   for (auto& option : options) {
296     switch (option->type_) {
297       case ConfigurationOptionType::MTU: {
298         auto* config = MtuConfigurationOption::Specialize(option.get());
299         if (config->mtu_ < kMinimumClassicMtu) {
300           LOG_WARN("Configuration request with Invalid MTU");
301           config->mtu_ = kDefaultClassicMtu;
302           rsp_options.emplace_back(std::make_unique<MtuConfigurationOption>(*config));
303           result = ConfigurationResponseResult::UNACCEPTABLE_PARAMETERS;
304         }
305         configuration_state.outgoing_mtu_ = config->mtu_;
306         break;
307       }
308       case ConfigurationOptionType::FLUSH_TIMEOUT: {
309         // TODO: Handle this configuration option
310         break;
311       }
312       case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: {
313         auto* config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
314         remote_rfc_mode = config->mode_;
315         if (config->mode_ == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
316           if (config->retransmission_time_out_ == 0) {
317             config->retransmission_time_out_ = 2000;
318           }
319           if (config->monitor_time_out_ == 0) {
320             config->monitor_time_out_ = 12000;
321           }
322         }
323         configuration_state.remote_retransmission_and_flow_control_ = *config;
324         configuration_state.retransmission_and_flow_control_mode_ = config->mode_;
325         rsp_options.emplace_back(std::make_unique<RetransmissionAndFlowControlConfigurationOption>(*config));
326         break;
327       }
328       case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: {
329         // We determine whether to use FCS or not when we send config request
330         break;
331       }
332       default:
333         if (option->is_hint_ != ConfigurationOptionIsHint::OPTION_IS_A_HINT) {
334           LOG_WARN("Received some unsupported configuration option: %d", static_cast<int>(option->type_));
335           auto response =
336               ConfigurationResponseBuilder::Create(signal_id.Value(), channel->GetRemoteCid(), is_continuation,
337                                                    ConfigurationResponseResult::UNKNOWN_OPTIONS, {});
338           enqueue_buffer_->Enqueue(std::move(response), handler_);
339           return;
340         }
341         break;
342     }
343   }
344 
345   auto initial_config_option = dynamic_service_manager_->GetService(channel->GetPsm())->GetConfigOption();
346 
347   if (remote_rfc_mode == RetransmissionAndFlowControlModeOption::L2CAP_BASIC &&
348       initial_config_option.channel_mode ==
349           DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION) {
350     LOG_WARN("ERTM mandatory not allow mode configuration, disconnect channel.");
351     SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid());
352     return;
353   }
354 
355   if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ) {
356     std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_);
357     if (channel->local_initiated_) {
358       link_->NotifyChannelCreation(cid, std::move(user_channel));
359     } else {
360       dynamic_service_manager_->GetService(channel->GetPsm())->NotifyChannelCreation(std::move(user_channel));
361     }
362     configuration_state.state_ = ChannelConfigurationState::State::CONFIGURED;
363     data_pipeline_manager_->AttachChannel(cid, channel, l2cap::internal::DataPipelineManager::ChannelMode::BASIC);
364     data_pipeline_manager_->UpdateClassicConfiguration(cid, configuration_state);
365   } else if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ_RSP) {
366     configuration_state.state_ = ChannelConfigurationState::State::WAIT_CONFIG_RSP;
367   }
368 
369   auto response = ConfigurationResponseBuilder::Create(signal_id.Value(), channel->GetRemoteCid(), is_continuation,
370                                                        result, std::move(rsp_options));
371   enqueue_buffer_->Enqueue(std::move(response), handler_);
372 }
373 
SendInitialConfigRequest(Cid local_cid)374 void ClassicSignallingManager::SendInitialConfigRequest(Cid local_cid) {
375   auto channel = channel_allocator_->FindChannelByCid(local_cid);
376   auto psm = channel->GetPsm();
377   auto& configuration_state = channel_configuration_[local_cid];
378   auto* service = dynamic_service_manager_->GetService(psm);
379   auto initial_config = service->GetConfigOption();
380 
381   auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
382   mtu_configuration->mtu_ = initial_config.incoming_mtu;
383   configuration_state.incoming_mtu_ = initial_config.incoming_mtu;
384 
385   auto fcs_option = std::make_unique<FrameCheckSequenceOption>();
386   fcs_option->fcs_type_ = FcsType::NO_FCS;
387   configuration_state.fcs_type_ = FcsType::NO_FCS;
388   if (link_->GetRemoteSupportsFcs()) {
389     fcs_option->fcs_type_ = FcsType::DEFAULT;
390     configuration_state.fcs_type_ = FcsType::DEFAULT;
391   }
392 
393   auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
394   switch (initial_config.channel_mode) {
395     case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC:
396       retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
397       configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
398       break;
399     case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION:
400     case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION_OPTIONAL:
401       retransmission_flow_control_configuration->mode_ =
402           RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
403       configuration_state.retransmission_and_flow_control_mode_ =
404           RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
405       // TODO: Decide where to put initial values
406       retransmission_flow_control_configuration->tx_window_size_ = 10;
407       retransmission_flow_control_configuration->max_transmit_ = 20;
408       retransmission_flow_control_configuration->retransmission_time_out_ = 2000;
409       retransmission_flow_control_configuration->monitor_time_out_ = 12000;
410       retransmission_flow_control_configuration->maximum_pdu_size_ = 1010;
411       break;
412   }
413   configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration;
414 
415   std::vector<std::unique_ptr<ConfigurationOption>> config;
416   config.emplace_back(std::move(mtu_configuration));
417   if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) {
418     config.emplace_back(std::move(retransmission_flow_control_configuration));
419     config.emplace_back(std::move(fcs_option));
420   }
421   send_configuration_request(channel->GetRemoteCid(), std::move(config));
422 }
423 
negotiate_configuration(Cid cid,Continuation is_continuation,std::vector<std::unique_ptr<ConfigurationOption>> options)424 void ClassicSignallingManager::negotiate_configuration(Cid cid, Continuation is_continuation,
425                                                        std::vector<std::unique_ptr<ConfigurationOption>> options) {
426   auto channel = channel_allocator_->FindChannelByCid(cid);
427   auto& configuration_state = channel_configuration_[channel->GetCid()];
428   std::vector<std::unique_ptr<ConfigurationOption>> negotiation_config;
429   bool can_negotiate = false;
430   for (auto& option : options) {
431     switch (option->type_) {
432       case ConfigurationOptionType::MTU: {
433         // MTU is non-negotiable option. Use default mtu size
434         auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
435         mtu_configuration->mtu_ = kDefaultClassicMtu;
436         configuration_state.incoming_mtu_ = kDefaultClassicMtu;
437         negotiation_config.emplace_back(std::move(mtu_configuration));
438         can_negotiate = true;
439         break;
440       }
441       case ConfigurationOptionType::FRAME_CHECK_SEQUENCE:
442       case ConfigurationOptionType::FLUSH_TIMEOUT: {
443         // TODO: Handle these two configuration options negotiation.
444         can_negotiate = true;
445         break;
446       }
447       case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: {
448         auto* config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
449         if (config->mode_ == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
450           configuration_state.retransmission_and_flow_control_mode_ = config->mode_;
451           configuration_state.local_retransmission_and_flow_control_ = *config;
452           negotiation_config.emplace_back(std::make_unique<RetransmissionAndFlowControlConfigurationOption>(*config));
453         } else if (config->mode_ == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) {
454           auto initial_config_option = dynamic_service_manager_->GetService(channel->GetPsm())->GetConfigOption();
455           if (initial_config_option.channel_mode ==
456               DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION) {
457             // ERTM mandatory is not allow negotiating of retransmission and flow control mode, disconnect channel
458             SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid());
459             return;
460           } else if (initial_config_option.channel_mode ==
461                      DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::
462                          ENHANCED_RETRANSMISSION_OPTIONAL) {
463             can_negotiate = true;
464             negotiation_config.emplace_back(std::make_unique<RetransmissionAndFlowControlConfigurationOption>(*config));
465           }
466         } else {
467           // Not support other retransmission and flow control mode, disconnect channel.
468           SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid());
469           return;
470         }
471         break;
472       }
473       default:
474         LOG_WARN("Received some unsupported configuration option: %d", static_cast<int>(option->type_));
475         return;
476     }
477   }
478   if (can_negotiate) {
479     send_configuration_request(channel->GetRemoteCid(), std::move(negotiation_config));
480   } else {
481     LOG_DEBUG("No suggested parameter received");
482   }
483 }
484 
OnConfigurationResponse(SignalId signal_id,Cid cid,Continuation is_continuation,ConfigurationResponseResult result,std::vector<std::unique_ptr<ConfigurationOption>> options)485 void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid cid, Continuation is_continuation,
486                                                        ConfigurationResponseResult result,
487                                                        std::vector<std::unique_ptr<ConfigurationOption>> options) {
488   if (command_just_sent_.signal_id_ != signal_id ||
489       command_just_sent_.command_code_ != CommandCode::CONFIGURATION_REQUEST) {
490     LOG_WARN("Unexpected response: no pending request. Expected signal id %d type %s, got %d",
491              command_just_sent_.signal_id_.Value(), CommandCodeText(command_just_sent_.command_code_).data(),
492              signal_id.Value());
493     return;
494   }
495 
496   auto channel = channel_allocator_->FindChannelByCid(cid);
497   if (channel == nullptr) {
498     LOG_WARN("Configuration request for an unknown channel");
499     handle_send_next_command();
500     return;
501   }
502 
503   switch (result) {
504     default:
505     case ConfigurationResponseResult::REJECTED:
506     case ConfigurationResponseResult::UNKNOWN_OPTIONS:
507     case ConfigurationResponseResult::FLOW_SPEC_REJECTED:
508       LOG_WARN("Configuration response not SUCCESS: %s", ConfigurationResponseResultText(result).c_str());
509       alarm_.Cancel();
510       handle_send_next_command();
511       return;
512 
513     case ConfigurationResponseResult::PENDING:
514       alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
515                       kTimeout);
516       return;
517 
518     case ConfigurationResponseResult::UNACCEPTABLE_PARAMETERS:
519       LOG_INFO("Configuration response with unacceptable parameters");
520       alarm_.Cancel();
521       negotiate_configuration(cid, is_continuation, std::move(options));
522       handle_send_next_command();
523       return;
524 
525     case ConfigurationResponseResult::SUCCESS:
526       break;
527   }
528   auto& configuration_state = channel_configuration_[channel->GetCid()];
529 
530   for (auto& option : options) {
531     switch (option->type_) {
532       case ConfigurationOptionType::MTU: {
533         auto config = MtuConfigurationOption::Specialize(option.get());
534         configuration_state.incoming_mtu_ = config->mtu_;
535         break;
536       }
537       case ConfigurationOptionType::FLUSH_TIMEOUT: {
538         // TODO: Handle this configuration option
539         break;
540       }
541       case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: {
542         auto config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
543         if (configuration_state.retransmission_and_flow_control_mode_ != config->mode_) {
544           SendDisconnectionRequest(cid, channel->GetRemoteCid());
545           alarm_.Cancel();
546           handle_send_next_command();
547           return;
548         }
549         configuration_state.local_retransmission_and_flow_control_ = *config;
550         break;
551       }
552       case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: {
553         configuration_state.fcs_type_ = FrameCheckSequenceOption::Specialize(option.get())->fcs_type_;
554         break;
555       }
556       default:
557         LOG_WARN("Received some unsupported configuration option: %d", static_cast<int>(option->type_));
558         alarm_.Cancel();
559         handle_send_next_command();
560         return;
561     }
562   }
563 
564   if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_RSP) {
565     std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_);
566     if (channel->local_initiated_) {
567       link_->NotifyChannelCreation(cid, std::move(user_channel));
568     } else {
569       dynamic_service_manager_->GetService(channel->GetPsm())->NotifyChannelCreation(std::move(user_channel));
570     }
571     configuration_state.state_ = ChannelConfigurationState::State::CONFIGURED;
572     data_pipeline_manager_->AttachChannel(cid, channel, l2cap::internal::DataPipelineManager::ChannelMode::BASIC);
573     data_pipeline_manager_->UpdateClassicConfiguration(cid, configuration_state);
574   } else if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ_RSP) {
575     configuration_state.state_ = ChannelConfigurationState::State::WAIT_CONFIG_REQ;
576   }
577 
578   alarm_.Cancel();
579   handle_send_next_command();
580 }
581 
OnDisconnectionRequest(SignalId signal_id,Cid cid,Cid remote_cid)582 void ClassicSignallingManager::OnDisconnectionRequest(SignalId signal_id, Cid cid, Cid remote_cid) {
583   // TODO: check cid match
584   auto channel = channel_allocator_->FindChannelByCid(cid);
585   if (channel == nullptr) {
586     LOG_WARN("Disconnect request for an unknown channel");
587     return;
588   }
589   auto builder = DisconnectionResponseBuilder::Create(signal_id.Value(), cid, remote_cid);
590   enqueue_buffer_->Enqueue(std::move(builder), handler_);
591   channel->OnClosed(hci::ErrorCode::SUCCESS);
592   auto& configuration_state = channel_configuration_[channel->GetCid()];
593   if (configuration_state.state_ == configuration_state.CONFIGURED) {
594     data_pipeline_manager_->DetachChannel(cid);
595   }
596   link_->FreeDynamicChannel(cid);
597   channel_configuration_.erase(cid);
598 }
599 
OnDisconnectionResponse(SignalId signal_id,Cid remote_cid,Cid cid)600 void ClassicSignallingManager::OnDisconnectionResponse(SignalId signal_id, Cid remote_cid, Cid cid) {
601   if (command_just_sent_.signal_id_ != signal_id ||
602       command_just_sent_.command_code_ != CommandCode::DISCONNECTION_REQUEST) {
603     LOG_WARN("Unexpected response: no pending request. Expected signal id %d type %s, got %d",
604              command_just_sent_.signal_id_.Value(), CommandCodeText(command_just_sent_.command_code_).data(),
605              signal_id.Value());
606     return;
607   }
608 
609   alarm_.Cancel();
610 
611   auto channel = channel_allocator_->FindChannelByCid(cid);
612   if (channel == nullptr) {
613     LOG_WARN("Disconnect response for an unknown channel");
614     handle_send_next_command();
615     return;
616   }
617 
618   channel->OnClosed(hci::ErrorCode::SUCCESS);
619   auto& configuration_state = channel_configuration_[cid];
620   if (configuration_state.state_ == configuration_state.CONFIGURED) {
621     data_pipeline_manager_->DetachChannel(cid);
622   }
623   link_->FreeDynamicChannel(cid);
624   handle_send_next_command();
625   channel_configuration_.erase(cid);
626 }
627 
OnEchoRequest(SignalId signal_id,const PacketView<kLittleEndian> & packet)628 void ClassicSignallingManager::OnEchoRequest(SignalId signal_id, const PacketView<kLittleEndian>& packet) {
629   std::vector<uint8_t> packet_vector{packet.begin(), packet.end()};
630   auto raw_builder = std::make_unique<packet::RawBuilder>();
631   raw_builder->AddOctets(packet_vector);
632   auto builder = EchoResponseBuilder::Create(signal_id.Value(), std::move(raw_builder));
633   enqueue_buffer_->Enqueue(std::move(builder), handler_);
634 }
635 
OnEchoResponse(SignalId signal_id,const PacketView<kLittleEndian> & packet)636 void ClassicSignallingManager::OnEchoResponse(SignalId signal_id, const PacketView<kLittleEndian>& packet) {
637   if (command_just_sent_.signal_id_ != signal_id || command_just_sent_.command_code_ != CommandCode::ECHO_REQUEST) {
638     LOG_WARN("Unexpected response: no pending request. Expected signal id %d type %s, got %d",
639              command_just_sent_.signal_id_.Value(), CommandCodeText(command_just_sent_.command_code_).data(),
640              signal_id.Value());
641     return;
642   }
643   LOG_INFO("Echo response received");
644   alarm_.Cancel();
645   handle_send_next_command();
646 }
647 
OnInformationRequest(SignalId signal_id,InformationRequestInfoType type)648 void ClassicSignallingManager::OnInformationRequest(SignalId signal_id, InformationRequestInfoType type) {
649   switch (type) {
650     case InformationRequestInfoType::CONNECTIONLESS_MTU: {
651       auto response = InformationResponseConnectionlessMtuBuilder::Create(
652           signal_id.Value(), InformationRequestResult::SUCCESS, kDefaultClassicMtu);
653       enqueue_buffer_->Enqueue(std::move(response), handler_);
654       break;
655     }
656     case InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED: {
657       auto response = InformationResponseExtendedFeaturesBuilder::Create(
658           signal_id.Value(), InformationRequestResult::SUCCESS, 0, 0, 0, 1 /* ERTM */, 0 /* Streaming mode */,
659           1 /* FCS */, 0, 1 /* Fixed Channels */, 0, 0);
660       enqueue_buffer_->Enqueue(std::move(response), handler_);
661       break;
662     }
663     case InformationRequestInfoType::FIXED_CHANNELS_SUPPORTED: {
664       auto response = InformationResponseFixedChannelsBuilder::Create(
665           signal_id.Value(), InformationRequestResult::SUCCESS, fixed_service_manager_->GetSupportedFixedChannelMask());
666       enqueue_buffer_->Enqueue(std::move(response), handler_);
667       break;
668     }
669   }
670 }
671 
OnInformationResponse(SignalId signal_id,const InformationResponseView & response)672 void ClassicSignallingManager::OnInformationResponse(SignalId signal_id, const InformationResponseView& response) {
673   if (command_just_sent_.signal_id_ != signal_id ||
674       command_just_sent_.command_code_ != CommandCode::INFORMATION_REQUEST) {
675     LOG_WARN("Unexpected response: no pending request. Expected signal id %d type %s, got %d",
676              command_just_sent_.signal_id_.Value(), CommandCodeText(command_just_sent_.command_code_).data(),
677              signal_id.Value());
678     return;
679   }
680 
681   auto type = response.GetInfoType();
682   switch (type) {
683     case InformationRequestInfoType::CONNECTIONLESS_MTU: {
684       auto view = InformationResponseConnectionlessMtuView::Create(response);
685       if (!view.IsValid()) {
686         LOG_WARN("Invalid InformationResponseConnectionlessMtu received");
687         return;
688       }
689       link_->SetRemoteConnectionlessMtu(view.GetConnectionlessMtu());
690       break;
691     }
692     case InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED: {
693       auto view = InformationResponseExtendedFeaturesView::Create(response);
694       if (!view.IsValid()) {
695         LOG_WARN("Invalid InformationResponseExtendedFeatures received");
696         return;
697       }
698       link_->OnRemoteExtendedFeatureReceived(view.GetEnhancedRetransmissionMode(), view.GetFcsOption());
699       // We don't care about other parameters
700       break;
701     }
702     case InformationRequestInfoType::FIXED_CHANNELS_SUPPORTED: {
703       auto view = InformationResponseFixedChannelsView::Create(response);
704       if (!view.IsValid()) {
705         LOG_WARN("Invalid InformationResponseFixedChannel received");
706         return;
707       }
708       // We don't use fixed channels (connectionless or BR/EDR security) for now so we don't care
709       break;
710     }
711   }
712 
713   alarm_.Cancel();
714   handle_send_next_command();
715 }
716 
on_incoming_packet()717 void ClassicSignallingManager::on_incoming_packet() {
718   auto packet = signalling_channel_->GetQueueUpEnd()->TryDequeue();
719   auto command_list = GetCommandsFromPacketView(*packet);
720   for (auto& command : command_list) {
721     handle_one_command(command);
722   }
723 }
724 
handle_one_command(ControlView control_packet_view)725 void ClassicSignallingManager::handle_one_command(ControlView control_packet_view) {
726   if (!control_packet_view.IsValid()) {
727     LOG_WARN("Invalid signalling packet received");
728     return;
729   }
730   auto code = control_packet_view.GetCode();
731   switch (code) {
732     case CommandCode::COMMAND_REJECT: {
733       CommandRejectView command_reject_view = CommandRejectView::Create(control_packet_view);
734       if (!command_reject_view.IsValid()) {
735         return;
736       }
737       OnCommandReject(command_reject_view);
738       return;
739     }
740     case CommandCode::CONNECTION_REQUEST: {
741       ConnectionRequestView connection_request_view = ConnectionRequestView::Create(control_packet_view);
742       if (!connection_request_view.IsValid()) {
743         return;
744       }
745       OnConnectionRequest(control_packet_view.GetIdentifier(), connection_request_view.GetPsm(),
746                           connection_request_view.GetSourceCid());
747       return;
748     }
749     case CommandCode::CONNECTION_RESPONSE: {
750       ConnectionResponseView connection_response_view = ConnectionResponseView::Create(control_packet_view);
751       if (!connection_response_view.IsValid()) {
752         return;
753       }
754       OnConnectionResponse(connection_response_view.GetIdentifier(), connection_response_view.GetDestinationCid(),
755                            connection_response_view.GetSourceCid(), connection_response_view.GetResult(),
756                            connection_response_view.GetStatus());
757       return;
758     }
759     case CommandCode::CONFIGURATION_REQUEST: {
760       ConfigurationRequestView configuration_request_view = ConfigurationRequestView::Create(control_packet_view);
761       if (!configuration_request_view.IsValid()) {
762         return;
763       }
764       OnConfigurationRequest(configuration_request_view.GetIdentifier(), configuration_request_view.GetDestinationCid(),
765                              configuration_request_view.GetContinuation(), configuration_request_view.GetConfig());
766       return;
767     }
768     case CommandCode::CONFIGURATION_RESPONSE: {
769       ConfigurationResponseView configuration_response_view = ConfigurationResponseView::Create(control_packet_view);
770       if (!configuration_response_view.IsValid()) {
771         return;
772       }
773       OnConfigurationResponse(configuration_response_view.GetIdentifier(), configuration_response_view.GetSourceCid(),
774                               configuration_response_view.GetContinuation(), configuration_response_view.GetResult(),
775                               configuration_response_view.GetConfig());
776       return;
777     }
778     case CommandCode::DISCONNECTION_REQUEST: {
779       DisconnectionRequestView disconnection_request_view = DisconnectionRequestView::Create(control_packet_view);
780       if (!disconnection_request_view.IsValid()) {
781         return;
782       }
783       OnDisconnectionRequest(disconnection_request_view.GetIdentifier(), disconnection_request_view.GetDestinationCid(),
784                              disconnection_request_view.GetSourceCid());
785       return;
786     }
787     case CommandCode::DISCONNECTION_RESPONSE: {
788       DisconnectionResponseView disconnection_response_view = DisconnectionResponseView::Create(control_packet_view);
789       if (!disconnection_response_view.IsValid()) {
790         return;
791       }
792       OnDisconnectionResponse(disconnection_response_view.GetIdentifier(),
793                               disconnection_response_view.GetDestinationCid(),
794                               disconnection_response_view.GetSourceCid());
795       return;
796     }
797     case CommandCode::ECHO_REQUEST: {
798       EchoRequestView echo_request_view = EchoRequestView::Create(control_packet_view);
799       if (!echo_request_view.IsValid()) {
800         return;
801       }
802       OnEchoRequest(echo_request_view.GetIdentifier(), echo_request_view.GetPayload());
803       return;
804     }
805     case CommandCode::ECHO_RESPONSE: {
806       EchoResponseView echo_response_view = EchoResponseView::Create(control_packet_view);
807       if (!echo_response_view.IsValid()) {
808         return;
809       }
810       OnEchoResponse(echo_response_view.GetIdentifier(), echo_response_view.GetPayload());
811       return;
812     }
813     case CommandCode::INFORMATION_REQUEST: {
814       InformationRequestView information_request_view = InformationRequestView::Create(control_packet_view);
815       if (!information_request_view.IsValid()) {
816         return;
817       }
818       OnInformationRequest(information_request_view.GetIdentifier(), information_request_view.GetInfoType());
819       return;
820     }
821     case CommandCode::INFORMATION_RESPONSE: {
822       InformationResponseView information_response_view = InformationResponseView::Create(control_packet_view);
823       if (!information_response_view.IsValid()) {
824         return;
825       }
826       OnInformationResponse(information_response_view.GetIdentifier(), information_response_view);
827       return;
828     }
829     default:
830       LOG_WARN("Unhandled event 0x%x", static_cast<int>(code));
831       auto builder = CommandRejectNotUnderstoodBuilder::Create(control_packet_view.GetIdentifier());
832       enqueue_buffer_->Enqueue(std::move(builder), handler_);
833       return;
834   }
835 }
836 
send_connection_response(SignalId signal_id,Cid remote_cid,Cid local_cid,ConnectionResponseResult result,ConnectionResponseStatus status)837 void ClassicSignallingManager::send_connection_response(SignalId signal_id, Cid remote_cid, Cid local_cid,
838                                                         ConnectionResponseResult result,
839                                                         ConnectionResponseStatus status) {
840   auto builder = ConnectionResponseBuilder::Create(signal_id.Value(), local_cid, remote_cid, result, status);
841   enqueue_buffer_->Enqueue(std::move(builder), handler_);
842 }
843 
on_command_timeout()844 void ClassicSignallingManager::on_command_timeout() {
845   LOG_WARN("Response time out");
846   if (command_just_sent_.signal_id_ == kInvalidSignalId) {
847     LOG_ERROR("No pending command");
848     return;
849   }
850   LOG_WARN("Response time out for %s", CommandCodeText(command_just_sent_.command_code_).c_str());
851   switch (command_just_sent_.command_code_) {
852     case CommandCode::CONNECTION_REQUEST: {
853       DynamicChannelManager::ConnectionResult connection_result{
854           .connection_result_code = DynamicChannelManager::ConnectionResultCode::FAIL_L2CAP_ERROR,
855           .hci_error = hci::ErrorCode::SUCCESS,
856           .l2cap_connection_response_result = ConnectionResponseResult::NO_RESOURCES_AVAILABLE,
857       };
858       link_->OnOutgoingConnectionRequestFail(command_just_sent_.source_cid_, connection_result);
859       break;
860     }
861     case CommandCode::CONFIGURATION_REQUEST: {
862       auto channel = channel_allocator_->FindChannelByRemoteCid(command_just_sent_.destination_cid_);
863       SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid());
864       return;
865     }
866     case CommandCode::INFORMATION_REQUEST: {
867       if (command_just_sent_.info_type_ == InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED) {
868         link_->OnRemoteExtendedFeatureReceived(false, false);
869       }
870       break;
871     }
872     default:
873       break;
874   }
875   handle_send_next_command();
876 }
877 
handle_send_next_command()878 void ClassicSignallingManager::handle_send_next_command() {
879   command_just_sent_.signal_id_ = kInvalidSignalId;
880   if (pending_commands_.empty()) {
881     return;
882   }
883   command_just_sent_ = std::move(pending_commands_.front());
884   pending_commands_.pop();
885 
886   auto signal_id = command_just_sent_.signal_id_;
887   auto psm = command_just_sent_.psm_;
888   auto source_cid = command_just_sent_.source_cid_;
889   auto destination_cid = command_just_sent_.destination_cid_;
890   auto info_type = command_just_sent_.info_type_;
891   auto config = std::move(command_just_sent_.config_);
892   switch (command_just_sent_.command_code_) {
893     case CommandCode::CONNECTION_REQUEST: {
894       auto builder = ConnectionRequestBuilder::Create(signal_id.Value(), psm, source_cid);
895       enqueue_buffer_->Enqueue(std::move(builder), handler_);
896       alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
897                       kTimeout);
898       break;
899     }
900     case CommandCode::CONFIGURATION_REQUEST: {
901       auto builder =
902           ConfigurationRequestBuilder::Create(signal_id.Value(), destination_cid, Continuation::END, std::move(config));
903       enqueue_buffer_->Enqueue(std::move(builder), handler_);
904       alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
905                       kTimeout);
906       break;
907     }
908     case CommandCode::DISCONNECTION_REQUEST: {
909       auto builder = DisconnectionRequestBuilder::Create(signal_id.Value(), destination_cid, source_cid);
910       enqueue_buffer_->Enqueue(std::move(builder), handler_);
911       alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
912                       kTimeout);
913       break;
914     }
915     case CommandCode::INFORMATION_REQUEST: {
916       auto builder = InformationRequestBuilder::Create(signal_id.Value(), info_type);
917       enqueue_buffer_->Enqueue(std::move(builder), handler_);
918       alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
919                       kTimeout);
920       break;
921     }
922     default:
923       LOG_WARN("Unsupported command code 0x%x", static_cast<int>(command_just_sent_.command_code_));
924   }
925 }
926 
927 }  // namespace internal
928 }  // namespace classic
929 }  // namespace l2cap
930 }  // namespace bluetooth
931