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