Loading system/gd/l2cap/classic/cert/cert.cc +14 −4 Original line number Diff line number Diff line Loading @@ -164,10 +164,10 @@ class L2capClassicModuleCertService : public L2capClassicModuleCert::Service { if (request->retransmission_config().mode() == ChannelRetransmissionFlowControlMode::ERTM) { auto option = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); option->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; option->tx_window_size_ = 10; option->max_transmit_ = 20; option->retransmission_time_out_ = 2000; option->monitor_time_out_ = 12000; option->tx_window_size_ = 5; option->max_transmit_ = 1; option->retransmission_time_out_ = 1000; option->monitor_time_out_ = 2000; option->maximum_pdu_size_ = 1010; config.push_back(std::move(option)); } Loading Loading @@ -407,6 +407,16 @@ class L2capClassicModuleCertService : public L2capClassicModuleCert::Service { LogEvent(response); break; } case CommandCode::DISCONNECTION_REQUEST: { DisconnectionRequestView view = DisconnectionRequestView::Create(control_view); ASSERT(view.IsValid()); FetchL2capLogResponse response; response.mutable_disconnection_request()->set_signal_id(control_view.GetIdentifier()); response.mutable_disconnection_request()->set_dcid(view.GetDestinationCid()); response.mutable_disconnection_request()->set_scid(view.GetSourceCid()); LogEvent(response); break; } case CommandCode::DISCONNECTION_RESPONSE: { DisconnectionResponseView view = DisconnectionResponseView::Create(control_view); ASSERT(view.IsValid()); Loading system/gd/l2cap/classic/cert/simple_l2cap_test.py +53 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ class SimpleL2capTest(GdBaseTestClass): self.cert_device.l2cap.SendConfigurationResponse(l2cap_cert_pb2.ConfigurationResponse( scid=dcid, signal_id=log.signal_id, retransmission_config=l2cap_cert_pb2.ChannelRetransmissionFlowControlConfig(mode=self.retransmission_mode) )) log_event_handler.on(is_configuration_request, handle_configuration_request) Loading Loading @@ -404,3 +405,55 @@ class SimpleL2capTest(GdBaseTestClass): assert info_response[0][0] == signal_id assert info_response[0][1] == expected_log_type assert info_response[0][2] | expected_mask == expected_mask def test_transmit_i_frames(self): """ L2CAP/ERM/BV-01-C [Transmit I-frames] """ self.retransmission_mode = l2cap_cert_pb2.ChannelRetransmissionFlowControlMode.ERTM self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2)) self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=0x33, retransmission_mode=l2cap_facade_pb2.RetransmissionFlowControlMode.ERTM)) self._setup_link() scid = 0x0101 self._open_channel(scid=scid) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=1, s=0)) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=2, s=0)) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=3, s=0)) data_received = [] event_handler = EventHandler() def on_data_received(log): log = log.data_packet data_received.append((log.channel, log.payload)) event_handler.on(lambda log : log.HasField("data_packet"), on_data_received) logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest()) event_handler.execute(logs) assert len(data_received) == 3 def test_s_frame_transmissions_exceed_max_transmit(self): """ L2CAP/ERM/BV-11-C [S-Frame Transmissions Exceed MaxTransmit] """ self.retransmission_mode = l2cap_cert_pb2.ChannelRetransmissionFlowControlMode.ERTM self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2)) self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=0x33, retransmission_mode=l2cap_facade_pb2.RetransmissionFlowControlMode.ERTM)) self._setup_link() scid = 0x0101 self._open_channel(scid=scid) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) # Retransmission timer = 1, 1 * monitor timer = 2, so total timeout is 3 time.sleep(4) disconnect_request = [] event_handler = EventHandler() def on_disconnect_req(log): log = log.disconnection_request disconnect_request.append((log.dcid, log.scid)) event_handler.on(is_disconnection_request, on_disconnect_req) logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest()) event_handler.execute(logs) assert len(disconnect_request) == 1, "No disconnect request received" assert disconnect_request[0] == (scid, self.scid_dcid_map[scid]), "Incorrect disconnect request received: scid %r, dcid %r" % (disconnect_request[0][0], disconnect_request[0][1]) system/gd/l2cap/classic/dynamic_channel.h 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "l2cap/dynamic_channel.h" namespace bluetooth { namespace l2cap { namespace classic { using DynamicChannel = l2cap::DynamicChannel; } // namespace classic } // namespace l2cap } // namespace bluetooth system/gd/l2cap/classic/dynamic_channel_manager.h +1 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,9 @@ #include "hci/acl_manager.h" #include "hci/address.h" #include "l2cap/classic/dynamic_channel.h" #include "l2cap/classic/dynamic_channel_configuration_option.h" #include "l2cap/classic/dynamic_channel_service.h" #include "l2cap/dynamic_channel.h" #include "l2cap/l2cap_packets.h" #include "l2cap/psm.h" #include "l2cap/security_policy.h" Loading system/gd/l2cap/classic/internal/dynamic_channel_service_impl.h +1 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,10 @@ #include "common/bind.h" #include "l2cap/classic/dynamic_channel.h" #include "l2cap/classic/dynamic_channel_configuration_option.h" #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/dynamic_channel_service.h" #include "l2cap/dynamic_channel.h" namespace bluetooth { namespace l2cap { Loading Loading
system/gd/l2cap/classic/cert/cert.cc +14 −4 Original line number Diff line number Diff line Loading @@ -164,10 +164,10 @@ class L2capClassicModuleCertService : public L2capClassicModuleCert::Service { if (request->retransmission_config().mode() == ChannelRetransmissionFlowControlMode::ERTM) { auto option = std::make_unique<RetransmissionAndFlowControlConfigurationOption>(); option->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION; option->tx_window_size_ = 10; option->max_transmit_ = 20; option->retransmission_time_out_ = 2000; option->monitor_time_out_ = 12000; option->tx_window_size_ = 5; option->max_transmit_ = 1; option->retransmission_time_out_ = 1000; option->monitor_time_out_ = 2000; option->maximum_pdu_size_ = 1010; config.push_back(std::move(option)); } Loading Loading @@ -407,6 +407,16 @@ class L2capClassicModuleCertService : public L2capClassicModuleCert::Service { LogEvent(response); break; } case CommandCode::DISCONNECTION_REQUEST: { DisconnectionRequestView view = DisconnectionRequestView::Create(control_view); ASSERT(view.IsValid()); FetchL2capLogResponse response; response.mutable_disconnection_request()->set_signal_id(control_view.GetIdentifier()); response.mutable_disconnection_request()->set_dcid(view.GetDestinationCid()); response.mutable_disconnection_request()->set_scid(view.GetSourceCid()); LogEvent(response); break; } case CommandCode::DISCONNECTION_RESPONSE: { DisconnectionResponseView view = DisconnectionResponseView::Create(control_view); ASSERT(view.IsValid()); Loading
system/gd/l2cap/classic/cert/simple_l2cap_test.py +53 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ class SimpleL2capTest(GdBaseTestClass): self.cert_device.l2cap.SendConfigurationResponse(l2cap_cert_pb2.ConfigurationResponse( scid=dcid, signal_id=log.signal_id, retransmission_config=l2cap_cert_pb2.ChannelRetransmissionFlowControlConfig(mode=self.retransmission_mode) )) log_event_handler.on(is_configuration_request, handle_configuration_request) Loading Loading @@ -404,3 +405,55 @@ class SimpleL2capTest(GdBaseTestClass): assert info_response[0][0] == signal_id assert info_response[0][1] == expected_log_type assert info_response[0][2] | expected_mask == expected_mask def test_transmit_i_frames(self): """ L2CAP/ERM/BV-01-C [Transmit I-frames] """ self.retransmission_mode = l2cap_cert_pb2.ChannelRetransmissionFlowControlMode.ERTM self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2)) self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=0x33, retransmission_mode=l2cap_facade_pb2.RetransmissionFlowControlMode.ERTM)) self._setup_link() scid = 0x0101 self._open_channel(scid=scid) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=1, s=0)) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=2, s=0)) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=3, s=0)) data_received = [] event_handler = EventHandler() def on_data_received(log): log = log.data_packet data_received.append((log.channel, log.payload)) event_handler.on(lambda log : log.HasField("data_packet"), on_data_received) logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest()) event_handler.execute(logs) assert len(data_received) == 3 def test_s_frame_transmissions_exceed_max_transmit(self): """ L2CAP/ERM/BV-11-C [S-Frame Transmissions Exceed MaxTransmit] """ self.retransmission_mode = l2cap_cert_pb2.ChannelRetransmissionFlowControlMode.ERTM self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2)) self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=0x33, retransmission_mode=l2cap_facade_pb2.RetransmissionFlowControlMode.ERTM)) self._setup_link() scid = 0x0101 self._open_channel(scid=scid) self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc')) # Retransmission timer = 1, 1 * monitor timer = 2, so total timeout is 3 time.sleep(4) disconnect_request = [] event_handler = EventHandler() def on_disconnect_req(log): log = log.disconnection_request disconnect_request.append((log.dcid, log.scid)) event_handler.on(is_disconnection_request, on_disconnect_req) logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest()) event_handler.execute(logs) assert len(disconnect_request) == 1, "No disconnect request received" assert disconnect_request[0] == (scid, self.scid_dcid_map[scid]), "Incorrect disconnect request received: scid %r, dcid %r" % (disconnect_request[0][0], disconnect_request[0][1])
system/gd/l2cap/classic/dynamic_channel.h 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "l2cap/dynamic_channel.h" namespace bluetooth { namespace l2cap { namespace classic { using DynamicChannel = l2cap::DynamicChannel; } // namespace classic } // namespace l2cap } // namespace bluetooth
system/gd/l2cap/classic/dynamic_channel_manager.h +1 −1 Original line number Diff line number Diff line Loading @@ -19,9 +19,9 @@ #include "hci/acl_manager.h" #include "hci/address.h" #include "l2cap/classic/dynamic_channel.h" #include "l2cap/classic/dynamic_channel_configuration_option.h" #include "l2cap/classic/dynamic_channel_service.h" #include "l2cap/dynamic_channel.h" #include "l2cap/l2cap_packets.h" #include "l2cap/psm.h" #include "l2cap/security_policy.h" Loading
system/gd/l2cap/classic/internal/dynamic_channel_service_impl.h +1 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,10 @@ #include "common/bind.h" #include "l2cap/classic/dynamic_channel.h" #include "l2cap/classic/dynamic_channel_configuration_option.h" #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/dynamic_channel_service.h" #include "l2cap/dynamic_channel.h" namespace bluetooth { namespace l2cap { Loading