Loading system/gd/l2cap/classic/cert/l2cap_test.py +24 −23 Original line number Diff line number Diff line Loading @@ -152,7 +152,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc' * 34) assertThat(cert_channel).emits( Loading Loading @@ -600,7 +600,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading Loading @@ -658,7 +658,7 @@ class L2capTest(GdBaseTestClass): self.cert_l2cap.turn_on_ertm() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading @@ -675,7 +675,7 @@ class L2capTest(GdBaseTestClass): self.cert_l2cap.turn_on_ertm() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b"abc") assertThat(cert_channel).emits( Loading Loading @@ -727,7 +727,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading Loading @@ -755,7 +755,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) for i in range(3): cert_channel.send_i_frame( Loading Loading @@ -794,7 +794,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) for i in range(3): cert_channel.send_i_frame( Loading Loading @@ -902,7 +902,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) cert_channel.send_s_frame(req_seq=0, p=Poll.POLL) assertThat(cert_channel).emits( Loading @@ -919,7 +919,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading Loading @@ -989,8 +989,9 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_unconfigured_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) config = CertL2cap.config_option_ertm(tx_window_size=2, max_transmit=2) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) config = CertL2cap.config_option_ertm( tx_window_size=2, max_transmit=2, fcs=FcsType.NO_FCS) cert_channel.verify_configuration_request_and_respond(options=config) cert_channel.send_configure_request(config) cert_channel.verify_configuration_response() Loading Loading @@ -1087,7 +1088,7 @@ class L2capTest(GdBaseTestClass): tx_window_size=tx_window_size, max_transmit=2) (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) cert_channel.send_i_frame( tx_seq=0, req_seq=0, f=Final.NOT_SET, payload=SAMPLE_PACKET) Loading Loading @@ -1122,7 +1123,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') Loading @@ -1145,7 +1146,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') Loading Loading @@ -1233,7 +1234,7 @@ class L2capTest(GdBaseTestClass): ertm_tx_window_size = 5 (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x41, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) cert_channel.send_i_frame(tx_seq=0, req_seq=0, payload=SAMPLE_PACKET) assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=1)) Loading Loading @@ -1264,7 +1265,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') dut_channel.send(b'abc') Loading Loading @@ -1297,7 +1298,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') dut_channel.send(b'abc') Loading Loading @@ -1329,7 +1330,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') dut_channel.send(b'abc') Loading Loading @@ -1375,6 +1376,8 @@ class L2capTest(GdBaseTestClass): Verify the IUT can accept a Configuration Request from the Lower Tester containing an F&EC option that specifies Enhanced Retransmission Mode """ asserts.skip("Need to send ERTM config request when we open from DUT") self._setup_link_from_cert() self._open_channel_from_dut( Loading Loading @@ -1435,9 +1438,7 @@ class L2capTest(GdBaseTestClass): """ self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_unconfigured_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) assertThat(self.cert_l2cap.get_control_channel()).emits( L2capMatchers.ConfigurationRequest()) cert_channel.send_configure_request( CertL2cap.config_option_basic_explicit()) mode=RetransmissionFlowControlMode.ERTM) cert_channel.verify_configuration_request_and_respond( options=CertL2cap.config_option_basic_explicit()) cert_channel.verify_disconnect_request() system/gd/l2cap/classic/internal/link.cc +16 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,13 @@ void Link::connect_to_pending_dynamic_channels() { } } void Link::send_pending_configuration_requests() { for (auto local_cid : pending_outgoing_configuration_request_list_) { signalling_manager_.SendInitialConfigRequest(local_cid); } pending_outgoing_configuration_request_list_.clear(); } void Link::OnOutgoingConnectionRequestFail(Cid local_cid) { if (local_cid_to_pending_dynamic_channel_connection_map_.find(local_cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()) { Loading @@ -178,6 +185,14 @@ void Link::OnOutgoingConnectionRequestFail(Cid local_cid) { dynamic_channel_allocator_.FreeChannel(local_cid); } void Link::SendInitialConfigRequestOrQueue(Cid local_cid) { if (remote_extended_feature_received_) { signalling_manager_.SendInitialConfigRequest(local_cid); } else { pending_outgoing_configuration_request_list_.push_back(local_cid); } } void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) { signalling_manager_.SendDisconnectionRequest(local_cid, remote_cid); } Loading Loading @@ -272,6 +287,7 @@ void Link::OnRemoteExtendedFeatureReceived(bool ertm_supported, bool fcs_support remote_supports_fcs_ = fcs_supported; remote_extended_feature_received_ = true; connect_to_pending_dynamic_channels(); send_pending_configuration_requests(); } void Link::AddChannelPendingingAuthentication(PendingAuthenticateDynamicChannelConnection pending_channel) { Loading system/gd/l2cap/classic/internal/link.h +4 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,8 @@ class Link : public l2cap::internal::ILink, public hci::ConnectionManagementCall // Invoked by signalling manager to indicate an outgoing connection request failed and link shall free resources virtual void OnOutgoingConnectionRequestFail(Cid local_cid); virtual void SendInitialConfigRequestOrQueue(Cid local_cid); virtual void SendInformationRequest(InformationRequestInfoType type); virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) override; Loading Loading @@ -168,6 +170,7 @@ class Link : public l2cap::internal::ILink, public hci::ConnectionManagementCall private: void connect_to_pending_dynamic_channels(); void send_pending_configuration_requests(); os::Handler* l2cap_handler_; l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_}; Loading @@ -188,6 +191,7 @@ class Link : public l2cap::internal::ILink, public hci::ConnectionManagementCall std::list<Link::PendingAuthenticateDynamicChannelConnection> pending_channel_list_; std::list<Psm> pending_dynamic_psm_list_; std::list<Link::PendingDynamicChannelConnection> pending_dynamic_channel_callback_list_; std::list<uint16_t> pending_outgoing_configuration_request_list_; DISALLOW_COPY_AND_ASSIGN(Link); }; Loading system/gd/l2cap/classic/internal/signalling_manager.cc +85 −111 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ void ClassicSignallingManager::SendConnectionRequest(Psm psm, Cid local_cid) { } } void ClassicSignallingManager::SendConfigurationRequest(Cid remote_cid, void ClassicSignallingManager::send_configuration_request(Cid remote_cid, std::vector<std::unique_ptr<ConfigurationOption>> config) { PendingCommand pending_command = {next_signal_id_, CommandCode::CONFIGURATION_REQUEST, {}, {}, remote_cid, {}, std::move(config)}; Loading @@ -93,16 +93,13 @@ void ClassicSignallingManager::SendConfigurationRequest(Cid remote_cid, } void ClassicSignallingManager::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) { command_just_sent_ = {next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}, {}}; PendingCommand pending_command = { next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}, {}}; next_signal_id_++; auto signal_id = command_just_sent_.signal_id_; auto source_cid = command_just_sent_.source_cid_; auto destination_cid = command_just_sent_.destination_cid_; auto builder = DisconnectionRequestBuilder::Create(signal_id.Value(), destination_cid, source_cid); enqueue_buffer_->Enqueue(std::move(builder), handler_); alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)), kTimeout); pending_commands_.push(std::move(pending_command)); if (command_just_sent_.signal_id_ == kInvalidSignalId) { handle_send_next_command(); } } void ClassicSignallingManager::SendInformationRequest(InformationRequestInfoType type) { Loading Loading @@ -157,51 +154,8 @@ void ClassicSignallingManager::OnConnectionRequest(SignalId signal_id, Psm psm, } send_connection_response(signal_id, remote_cid, new_channel->GetCid(), ConnectionResponseResult::SUCCESS, ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE); auto& configuration_state = channel_configuration_[new_channel->GetCid()]; auto* service = dynamic_service_manager_->GetService(psm); auto initial_config = service->GetConfigOption(); auto mtu_configuration = std::make_unique<MtuConfigurationOption>(); mtu_configuration->mtu_ = initial_config.incoming_mtu; configuration_state.incoming_mtu_ = initial_config.incoming_mtu; auto fcs_option = std::make_unique<FrameCheckSequenceOption>(); fcs_option->fcs_type_ = FcsType::NO_FCS; configuration_state.fcs_type_ = FcsType::NO_FCS; if (link_->GetRemoteSupportsFcs()) { fcs_option->fcs_type_ = FcsType::DEFAULT; configuration_state.fcs_type_ = FcsType::DEFAULT; } auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); switch (initial_config.channel_mode) { case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; break; case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION: case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION_OPTIONAL: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; // TODO: Decide where to put initial values retransmission_flow_control_configuration->tx_window_size_ = 10; retransmission_flow_control_configuration->max_transmit_ = 20; retransmission_flow_control_configuration->retransmission_time_out_ = 2000; retransmission_flow_control_configuration->monitor_time_out_ = 12000; retransmission_flow_control_configuration->maximum_pdu_size_ = 1010; break; } configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration; std::vector<std::unique_ptr<ConfigurationOption>> config; config.emplace_back(std::move(mtu_configuration)); if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) { config.emplace_back(std::move(retransmission_flow_control_configuration)); config.emplace_back(std::move(fcs_option)); } SendConfigurationRequest(remote_cid, std::move(config)); link_->SendInitialConfigRequestOrQueue(new_channel->GetCid()); } void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remote_cid, Cid cid, Loading Loading @@ -240,50 +194,7 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remo return; } auto& configuration_state = channel_configuration_[new_channel->GetCid()]; auto initial_config = link_->GetConfigurationForInitialConfiguration(new_channel->GetCid()); auto mtu_configuration = std::make_unique<MtuConfigurationOption>(); mtu_configuration->mtu_ = initial_config.incoming_mtu; configuration_state.incoming_mtu_ = initial_config.incoming_mtu; auto fcs_option = std::make_unique<FrameCheckSequenceOption>(); fcs_option->fcs_type_ = FcsType::DEFAULT; configuration_state.fcs_type_ = FcsType::DEFAULT; if (!link_->GetRemoteSupportsFcs()) { fcs_option->fcs_type_ = FcsType::NO_FCS; configuration_state.fcs_type_ = FcsType::NO_FCS; } auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); switch (initial_config.channel_mode) { case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; break; case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION: case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION_OPTIONAL: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; // TODO: Decide where to put initial values retransmission_flow_control_configuration->tx_window_size_ = 10; retransmission_flow_control_configuration->max_transmit_ = 20; retransmission_flow_control_configuration->retransmission_time_out_ = 2000; retransmission_flow_control_configuration->monitor_time_out_ = 12000; retransmission_flow_control_configuration->maximum_pdu_size_ = 1010; break; } configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration; std::vector<std::unique_ptr<ConfigurationOption>> config; config.emplace_back(std::move(mtu_configuration)); if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) { config.emplace_back(std::move(retransmission_flow_control_configuration)); config.emplace_back(std::move(fcs_option)); } SendConfigurationRequest(remote_cid, std::move(config)); link_->SendInitialConfigRequestOrQueue(cid); } void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid cid, Continuation is_continuation, Loading @@ -297,6 +208,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci auto& configuration_state = channel_configuration_[cid]; std::vector<std::unique_ptr<ConfigurationOption>> rsp_options; ConfigurationResponseResult result = ConfigurationResponseResult::SUCCESS; auto remote_rfc_mode = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; for (auto& option : options) { switch (option->type_) { Loading @@ -317,6 +229,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci } case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: { auto* config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get()); remote_rfc_mode = config->mode_; if (config->mode_ == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) { if (config->retransmission_time_out_ == 0) { config->retransmission_time_out_ = 2000; Loading @@ -324,14 +237,6 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci if (config->monitor_time_out_ == 0) { config->monitor_time_out_ = 12000; } } else if (config->mode_ == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) { auto initial_config_option = dynamic_service_manager_->GetService(channel->GetPsm())->GetConfigOption(); if (initial_config_option.channel_mode == DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION) { LOG_WARN("ERTM mandatory not allow mode configuration, disconnect channel."); SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid()); return; } } configuration_state.remote_retransmission_and_flow_control_ = *config; configuration_state.retransmission_and_flow_control_mode_ = config->mode_; Loading @@ -339,7 +244,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci break; } case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: { configuration_state.fcs_type_ = FrameCheckSequenceOption::Specialize(option.get())->fcs_type_; // We determine whether to use FCS or not when we send config request break; } default: Loading @@ -355,6 +260,16 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci } } auto initial_config_option = dynamic_service_manager_->GetService(channel->GetPsm())->GetConfigOption(); if (remote_rfc_mode == RetransmissionAndFlowControlModeOption::L2CAP_BASIC && initial_config_option.channel_mode == DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION) { LOG_WARN("ERTM mandatory not allow mode configuration, disconnect channel."); SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid()); return; } if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ) { std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_); if (channel->local_initiated_) { Loading @@ -374,6 +289,56 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci enqueue_buffer_->Enqueue(std::move(response), handler_); } void ClassicSignallingManager::SendInitialConfigRequest(Cid local_cid) { auto channel = channel_allocator_->FindChannelByCid(local_cid); auto psm = channel->GetPsm(); auto& configuration_state = channel_configuration_[local_cid]; auto* service = dynamic_service_manager_->GetService(psm); auto initial_config = service->GetConfigOption(); auto mtu_configuration = std::make_unique<MtuConfigurationOption>(); mtu_configuration->mtu_ = initial_config.incoming_mtu; configuration_state.incoming_mtu_ = initial_config.incoming_mtu; auto fcs_option = std::make_unique<FrameCheckSequenceOption>(); fcs_option->fcs_type_ = FcsType::NO_FCS; configuration_state.fcs_type_ = FcsType::NO_FCS; if (link_->GetRemoteSupportsFcs()) { fcs_option->fcs_type_ = FcsType::DEFAULT; configuration_state.fcs_type_ = FcsType::DEFAULT; } auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); switch (initial_config.channel_mode) { case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; break; case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION: case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION_OPTIONAL: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; // TODO: Decide where to put initial values retransmission_flow_control_configuration->tx_window_size_ = 10; retransmission_flow_control_configuration->max_transmit_ = 20; retransmission_flow_control_configuration->retransmission_time_out_ = 2000; retransmission_flow_control_configuration->monitor_time_out_ = 12000; retransmission_flow_control_configuration->maximum_pdu_size_ = 1010; break; } configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration; std::vector<std::unique_ptr<ConfigurationOption>> config; config.emplace_back(std::move(mtu_configuration)); if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) { config.emplace_back(std::move(retransmission_flow_control_configuration)); config.emplace_back(std::move(fcs_option)); } send_configuration_request(channel->GetRemoteCid(), std::move(config)); } void ClassicSignallingManager::negotiate_configuration(Cid cid, Continuation is_continuation, std::vector<std::unique_ptr<ConfigurationOption>> options) { auto channel = channel_allocator_->FindChannelByCid(cid); Loading Loading @@ -429,7 +394,9 @@ void ClassicSignallingManager::negotiate_configuration(Cid cid, Continuation is_ } } if (can_negotiate) { SendConfigurationRequest(channel->GetRemoteCid(), std::move(negotiation_config)); send_configuration_request(channel->GetRemoteCid(), std::move(negotiation_config)); } else { LOG_DEBUG("No suggested parameter received"); } } Loading Loading @@ -457,6 +424,7 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c case ConfigurationResponseResult::UNKNOWN_OPTIONS: case ConfigurationResponseResult::FLOW_SPEC_REJECTED: LOG_WARN("Configuration response not SUCCESS: %s", ConfigurationResponseResultText(result).c_str()); alarm_.Cancel(); handle_send_next_command(); return; Loading Loading @@ -490,7 +458,12 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c } case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: { auto config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get()); configuration_state.retransmission_and_flow_control_mode_ = config->mode_; if (configuration_state.retransmission_and_flow_control_mode_ != config->mode_) { SendDisconnectionRequest(cid, channel->GetRemoteCid()); alarm_.Cancel(); handle_send_next_command(); return; } configuration_state.local_retransmission_and_flow_control_ = *config; break; } Loading @@ -500,6 +473,8 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c } default: LOG_WARN("Received some unsupported configuration option: %d", static_cast<int>(option->type_)); alarm_.Cancel(); handle_send_next_command(); return; } } Loading Loading @@ -597,7 +572,6 @@ void ClassicSignallingManager::OnInformationRequest(SignalId signal_id, Informat break; } case InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED: { // TODO: implement this response auto response = InformationResponseExtendedFeaturesBuilder::Create( signal_id.Value(), InformationRequestResult::SUCCESS, 0, 0, 0, 1 /* ERTM */, 0 /* Streaming mode */, 1 /* FCS */, 0, 1 /* Fixed Channels */, 0, 0); Loading system/gd/l2cap/classic/internal/signalling_manager.h +3 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ class ClassicSignallingManager { void SendConnectionRequest(Psm psm, Cid local_cid); void SendConfigurationRequest(Cid remote_cid, std::vector<std::unique_ptr<ConfigurationOption>> config); void SendInitialConfigRequest(Cid local_cid); void SendDisconnectionRequest(Cid local_cid, Cid remote_cid); Loading Loading @@ -109,6 +109,8 @@ class ClassicSignallingManager { void negotiate_configuration(Cid cid, Continuation is_continuation, std::vector<std::unique_ptr<ConfigurationOption>>); void send_configuration_request(Cid remote_cid, std::vector<std::unique_ptr<ConfigurationOption>> config); os::Handler* handler_; Link* link_; l2cap::internal::DataPipelineManager* data_pipeline_manager_; Loading Loading
system/gd/l2cap/classic/cert/l2cap_test.py +24 −23 Original line number Diff line number Diff line Loading @@ -152,7 +152,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc' * 34) assertThat(cert_channel).emits( Loading Loading @@ -600,7 +600,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading Loading @@ -658,7 +658,7 @@ class L2capTest(GdBaseTestClass): self.cert_l2cap.turn_on_ertm() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading @@ -675,7 +675,7 @@ class L2capTest(GdBaseTestClass): self.cert_l2cap.turn_on_ertm() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b"abc") assertThat(cert_channel).emits( Loading Loading @@ -727,7 +727,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading Loading @@ -755,7 +755,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) for i in range(3): cert_channel.send_i_frame( Loading Loading @@ -794,7 +794,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) for i in range(3): cert_channel.send_i_frame( Loading Loading @@ -902,7 +902,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) cert_channel.send_s_frame(req_seq=0, p=Poll.POLL) assertThat(cert_channel).emits( Loading @@ -919,7 +919,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') assertThat(cert_channel).emits( Loading Loading @@ -989,8 +989,9 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_unconfigured_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) config = CertL2cap.config_option_ertm(tx_window_size=2, max_transmit=2) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) config = CertL2cap.config_option_ertm( tx_window_size=2, max_transmit=2, fcs=FcsType.NO_FCS) cert_channel.verify_configuration_request_and_respond(options=config) cert_channel.send_configure_request(config) cert_channel.verify_configuration_response() Loading Loading @@ -1087,7 +1088,7 @@ class L2capTest(GdBaseTestClass): tx_window_size=tx_window_size, max_transmit=2) (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) cert_channel.send_i_frame( tx_seq=0, req_seq=0, f=Final.NOT_SET, payload=SAMPLE_PACKET) Loading Loading @@ -1122,7 +1123,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') Loading @@ -1145,7 +1146,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') Loading Loading @@ -1233,7 +1234,7 @@ class L2capTest(GdBaseTestClass): ertm_tx_window_size = 5 (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x41, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) cert_channel.send_i_frame(tx_seq=0, req_seq=0, payload=SAMPLE_PACKET) assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=1)) Loading Loading @@ -1264,7 +1265,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') dut_channel.send(b'abc') Loading Loading @@ -1297,7 +1298,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') dut_channel.send(b'abc') Loading Loading @@ -1329,7 +1330,7 @@ class L2capTest(GdBaseTestClass): self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) mode=RetransmissionFlowControlMode.ERTM, fcs=FcsType.NO_FCS) dut_channel.send(b'abc') dut_channel.send(b'abc') Loading Loading @@ -1375,6 +1376,8 @@ class L2capTest(GdBaseTestClass): Verify the IUT can accept a Configuration Request from the Lower Tester containing an F&EC option that specifies Enhanced Retransmission Mode """ asserts.skip("Need to send ERTM config request when we open from DUT") self._setup_link_from_cert() self._open_channel_from_dut( Loading Loading @@ -1435,9 +1438,7 @@ class L2capTest(GdBaseTestClass): """ self._setup_link_from_cert() (dut_channel, cert_channel) = self._open_unconfigured_channel_from_cert( scid=0x41, psm=0x33, mode=RetransmissionFlowControlMode.ERTM) assertThat(self.cert_l2cap.get_control_channel()).emits( L2capMatchers.ConfigurationRequest()) cert_channel.send_configure_request( CertL2cap.config_option_basic_explicit()) mode=RetransmissionFlowControlMode.ERTM) cert_channel.verify_configuration_request_and_respond( options=CertL2cap.config_option_basic_explicit()) cert_channel.verify_disconnect_request()
system/gd/l2cap/classic/internal/link.cc +16 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,13 @@ void Link::connect_to_pending_dynamic_channels() { } } void Link::send_pending_configuration_requests() { for (auto local_cid : pending_outgoing_configuration_request_list_) { signalling_manager_.SendInitialConfigRequest(local_cid); } pending_outgoing_configuration_request_list_.clear(); } void Link::OnOutgoingConnectionRequestFail(Cid local_cid) { if (local_cid_to_pending_dynamic_channel_connection_map_.find(local_cid) != local_cid_to_pending_dynamic_channel_connection_map_.end()) { Loading @@ -178,6 +185,14 @@ void Link::OnOutgoingConnectionRequestFail(Cid local_cid) { dynamic_channel_allocator_.FreeChannel(local_cid); } void Link::SendInitialConfigRequestOrQueue(Cid local_cid) { if (remote_extended_feature_received_) { signalling_manager_.SendInitialConfigRequest(local_cid); } else { pending_outgoing_configuration_request_list_.push_back(local_cid); } } void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) { signalling_manager_.SendDisconnectionRequest(local_cid, remote_cid); } Loading Loading @@ -272,6 +287,7 @@ void Link::OnRemoteExtendedFeatureReceived(bool ertm_supported, bool fcs_support remote_supports_fcs_ = fcs_supported; remote_extended_feature_received_ = true; connect_to_pending_dynamic_channels(); send_pending_configuration_requests(); } void Link::AddChannelPendingingAuthentication(PendingAuthenticateDynamicChannelConnection pending_channel) { Loading
system/gd/l2cap/classic/internal/link.h +4 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,8 @@ class Link : public l2cap::internal::ILink, public hci::ConnectionManagementCall // Invoked by signalling manager to indicate an outgoing connection request failed and link shall free resources virtual void OnOutgoingConnectionRequestFail(Cid local_cid); virtual void SendInitialConfigRequestOrQueue(Cid local_cid); virtual void SendInformationRequest(InformationRequestInfoType type); virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) override; Loading Loading @@ -168,6 +170,7 @@ class Link : public l2cap::internal::ILink, public hci::ConnectionManagementCall private: void connect_to_pending_dynamic_channels(); void send_pending_configuration_requests(); os::Handler* l2cap_handler_; l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_}; Loading @@ -188,6 +191,7 @@ class Link : public l2cap::internal::ILink, public hci::ConnectionManagementCall std::list<Link::PendingAuthenticateDynamicChannelConnection> pending_channel_list_; std::list<Psm> pending_dynamic_psm_list_; std::list<Link::PendingDynamicChannelConnection> pending_dynamic_channel_callback_list_; std::list<uint16_t> pending_outgoing_configuration_request_list_; DISALLOW_COPY_AND_ASSIGN(Link); }; Loading
system/gd/l2cap/classic/internal/signalling_manager.cc +85 −111 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ void ClassicSignallingManager::SendConnectionRequest(Psm psm, Cid local_cid) { } } void ClassicSignallingManager::SendConfigurationRequest(Cid remote_cid, void ClassicSignallingManager::send_configuration_request(Cid remote_cid, std::vector<std::unique_ptr<ConfigurationOption>> config) { PendingCommand pending_command = {next_signal_id_, CommandCode::CONFIGURATION_REQUEST, {}, {}, remote_cid, {}, std::move(config)}; Loading @@ -93,16 +93,13 @@ void ClassicSignallingManager::SendConfigurationRequest(Cid remote_cid, } void ClassicSignallingManager::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) { command_just_sent_ = {next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}, {}}; PendingCommand pending_command = { next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}, {}}; next_signal_id_++; auto signal_id = command_just_sent_.signal_id_; auto source_cid = command_just_sent_.source_cid_; auto destination_cid = command_just_sent_.destination_cid_; auto builder = DisconnectionRequestBuilder::Create(signal_id.Value(), destination_cid, source_cid); enqueue_buffer_->Enqueue(std::move(builder), handler_); alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)), kTimeout); pending_commands_.push(std::move(pending_command)); if (command_just_sent_.signal_id_ == kInvalidSignalId) { handle_send_next_command(); } } void ClassicSignallingManager::SendInformationRequest(InformationRequestInfoType type) { Loading Loading @@ -157,51 +154,8 @@ void ClassicSignallingManager::OnConnectionRequest(SignalId signal_id, Psm psm, } send_connection_response(signal_id, remote_cid, new_channel->GetCid(), ConnectionResponseResult::SUCCESS, ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE); auto& configuration_state = channel_configuration_[new_channel->GetCid()]; auto* service = dynamic_service_manager_->GetService(psm); auto initial_config = service->GetConfigOption(); auto mtu_configuration = std::make_unique<MtuConfigurationOption>(); mtu_configuration->mtu_ = initial_config.incoming_mtu; configuration_state.incoming_mtu_ = initial_config.incoming_mtu; auto fcs_option = std::make_unique<FrameCheckSequenceOption>(); fcs_option->fcs_type_ = FcsType::NO_FCS; configuration_state.fcs_type_ = FcsType::NO_FCS; if (link_->GetRemoteSupportsFcs()) { fcs_option->fcs_type_ = FcsType::DEFAULT; configuration_state.fcs_type_ = FcsType::DEFAULT; } auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); switch (initial_config.channel_mode) { case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; break; case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION: case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION_OPTIONAL: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; // TODO: Decide where to put initial values retransmission_flow_control_configuration->tx_window_size_ = 10; retransmission_flow_control_configuration->max_transmit_ = 20; retransmission_flow_control_configuration->retransmission_time_out_ = 2000; retransmission_flow_control_configuration->monitor_time_out_ = 12000; retransmission_flow_control_configuration->maximum_pdu_size_ = 1010; break; } configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration; std::vector<std::unique_ptr<ConfigurationOption>> config; config.emplace_back(std::move(mtu_configuration)); if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) { config.emplace_back(std::move(retransmission_flow_control_configuration)); config.emplace_back(std::move(fcs_option)); } SendConfigurationRequest(remote_cid, std::move(config)); link_->SendInitialConfigRequestOrQueue(new_channel->GetCid()); } void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remote_cid, Cid cid, Loading Loading @@ -240,50 +194,7 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remo return; } auto& configuration_state = channel_configuration_[new_channel->GetCid()]; auto initial_config = link_->GetConfigurationForInitialConfiguration(new_channel->GetCid()); auto mtu_configuration = std::make_unique<MtuConfigurationOption>(); mtu_configuration->mtu_ = initial_config.incoming_mtu; configuration_state.incoming_mtu_ = initial_config.incoming_mtu; auto fcs_option = std::make_unique<FrameCheckSequenceOption>(); fcs_option->fcs_type_ = FcsType::DEFAULT; configuration_state.fcs_type_ = FcsType::DEFAULT; if (!link_->GetRemoteSupportsFcs()) { fcs_option->fcs_type_ = FcsType::NO_FCS; configuration_state.fcs_type_ = FcsType::NO_FCS; } auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); switch (initial_config.channel_mode) { case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; break; case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION: case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION_OPTIONAL: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; // TODO: Decide where to put initial values retransmission_flow_control_configuration->tx_window_size_ = 10; retransmission_flow_control_configuration->max_transmit_ = 20; retransmission_flow_control_configuration->retransmission_time_out_ = 2000; retransmission_flow_control_configuration->monitor_time_out_ = 12000; retransmission_flow_control_configuration->maximum_pdu_size_ = 1010; break; } configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration; std::vector<std::unique_ptr<ConfigurationOption>> config; config.emplace_back(std::move(mtu_configuration)); if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) { config.emplace_back(std::move(retransmission_flow_control_configuration)); config.emplace_back(std::move(fcs_option)); } SendConfigurationRequest(remote_cid, std::move(config)); link_->SendInitialConfigRequestOrQueue(cid); } void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid cid, Continuation is_continuation, Loading @@ -297,6 +208,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci auto& configuration_state = channel_configuration_[cid]; std::vector<std::unique_ptr<ConfigurationOption>> rsp_options; ConfigurationResponseResult result = ConfigurationResponseResult::SUCCESS; auto remote_rfc_mode = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; for (auto& option : options) { switch (option->type_) { Loading @@ -317,6 +229,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci } case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: { auto* config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get()); remote_rfc_mode = config->mode_; if (config->mode_ == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) { if (config->retransmission_time_out_ == 0) { config->retransmission_time_out_ = 2000; Loading @@ -324,14 +237,6 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci if (config->monitor_time_out_ == 0) { config->monitor_time_out_ = 12000; } } else if (config->mode_ == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) { auto initial_config_option = dynamic_service_manager_->GetService(channel->GetPsm())->GetConfigOption(); if (initial_config_option.channel_mode == DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION) { LOG_WARN("ERTM mandatory not allow mode configuration, disconnect channel."); SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid()); return; } } configuration_state.remote_retransmission_and_flow_control_ = *config; configuration_state.retransmission_and_flow_control_mode_ = config->mode_; Loading @@ -339,7 +244,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci break; } case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: { configuration_state.fcs_type_ = FrameCheckSequenceOption::Specialize(option.get())->fcs_type_; // We determine whether to use FCS or not when we send config request break; } default: Loading @@ -355,6 +260,16 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci } } auto initial_config_option = dynamic_service_manager_->GetService(channel->GetPsm())->GetConfigOption(); if (remote_rfc_mode == RetransmissionAndFlowControlModeOption::L2CAP_BASIC && initial_config_option.channel_mode == DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION) { LOG_WARN("ERTM mandatory not allow mode configuration, disconnect channel."); SendDisconnectionRequest(channel->GetCid(), channel->GetRemoteCid()); return; } if (configuration_state.state_ == ChannelConfigurationState::State::WAIT_CONFIG_REQ) { std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_); if (channel->local_initiated_) { Loading @@ -374,6 +289,56 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci enqueue_buffer_->Enqueue(std::move(response), handler_); } void ClassicSignallingManager::SendInitialConfigRequest(Cid local_cid) { auto channel = channel_allocator_->FindChannelByCid(local_cid); auto psm = channel->GetPsm(); auto& configuration_state = channel_configuration_[local_cid]; auto* service = dynamic_service_manager_->GetService(psm); auto initial_config = service->GetConfigOption(); auto mtu_configuration = std::make_unique<MtuConfigurationOption>(); mtu_configuration->mtu_ = initial_config.incoming_mtu; configuration_state.incoming_mtu_ = initial_config.incoming_mtu; auto fcs_option = std::make_unique<FrameCheckSequenceOption>(); fcs_option->fcs_type_ = FcsType::NO_FCS; configuration_state.fcs_type_ = FcsType::NO_FCS; if (link_->GetRemoteSupportsFcs()) { fcs_option->fcs_type_ = FcsType::DEFAULT; configuration_state.fcs_type_ = FcsType::DEFAULT; } auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); switch (initial_config.channel_mode) { case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC; break; case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION: case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION_OPTIONAL: retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; configuration_state.retransmission_and_flow_control_mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; // TODO: Decide where to put initial values retransmission_flow_control_configuration->tx_window_size_ = 10; retransmission_flow_control_configuration->max_transmit_ = 20; retransmission_flow_control_configuration->retransmission_time_out_ = 2000; retransmission_flow_control_configuration->monitor_time_out_ = 12000; retransmission_flow_control_configuration->maximum_pdu_size_ = 1010; break; } configuration_state.local_retransmission_and_flow_control_ = *retransmission_flow_control_configuration; std::vector<std::unique_ptr<ConfigurationOption>> config; config.emplace_back(std::move(mtu_configuration)); if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) { config.emplace_back(std::move(retransmission_flow_control_configuration)); config.emplace_back(std::move(fcs_option)); } send_configuration_request(channel->GetRemoteCid(), std::move(config)); } void ClassicSignallingManager::negotiate_configuration(Cid cid, Continuation is_continuation, std::vector<std::unique_ptr<ConfigurationOption>> options) { auto channel = channel_allocator_->FindChannelByCid(cid); Loading Loading @@ -429,7 +394,9 @@ void ClassicSignallingManager::negotiate_configuration(Cid cid, Continuation is_ } } if (can_negotiate) { SendConfigurationRequest(channel->GetRemoteCid(), std::move(negotiation_config)); send_configuration_request(channel->GetRemoteCid(), std::move(negotiation_config)); } else { LOG_DEBUG("No suggested parameter received"); } } Loading Loading @@ -457,6 +424,7 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c case ConfigurationResponseResult::UNKNOWN_OPTIONS: case ConfigurationResponseResult::FLOW_SPEC_REJECTED: LOG_WARN("Configuration response not SUCCESS: %s", ConfigurationResponseResultText(result).c_str()); alarm_.Cancel(); handle_send_next_command(); return; Loading Loading @@ -490,7 +458,12 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c } case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: { auto config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get()); configuration_state.retransmission_and_flow_control_mode_ = config->mode_; if (configuration_state.retransmission_and_flow_control_mode_ != config->mode_) { SendDisconnectionRequest(cid, channel->GetRemoteCid()); alarm_.Cancel(); handle_send_next_command(); return; } configuration_state.local_retransmission_and_flow_control_ = *config; break; } Loading @@ -500,6 +473,8 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c } default: LOG_WARN("Received some unsupported configuration option: %d", static_cast<int>(option->type_)); alarm_.Cancel(); handle_send_next_command(); return; } } Loading Loading @@ -597,7 +572,6 @@ void ClassicSignallingManager::OnInformationRequest(SignalId signal_id, Informat break; } case InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED: { // TODO: implement this response auto response = InformationResponseExtendedFeaturesBuilder::Create( signal_id.Value(), InformationRequestResult::SUCCESS, 0, 0, 0, 1 /* ERTM */, 0 /* Streaming mode */, 1 /* FCS */, 0, 1 /* Fixed Channels */, 0, 0); Loading
system/gd/l2cap/classic/internal/signalling_manager.h +3 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ class ClassicSignallingManager { void SendConnectionRequest(Psm psm, Cid local_cid); void SendConfigurationRequest(Cid remote_cid, std::vector<std::unique_ptr<ConfigurationOption>> config); void SendInitialConfigRequest(Cid local_cid); void SendDisconnectionRequest(Cid local_cid, Cid remote_cid); Loading Loading @@ -109,6 +109,8 @@ class ClassicSignallingManager { void negotiate_configuration(Cid cid, Continuation is_continuation, std::vector<std::unique_ptr<ConfigurationOption>>); void send_configuration_request(Cid remote_cid, std::vector<std::unique_ptr<ConfigurationOption>> config); os::Handler* handler_; Link* link_; l2cap::internal::DataPipelineManager* data_pipeline_manager_; Loading