Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41eff02d authored by Hansong Zhang's avatar Hansong Zhang Committed by Automerger Merge Worker
Browse files

L2cap handle multi command signalling packet am: 8a7f0596

Change-Id: Ifadb7d9bc459fa4dddfb55d720783653397bde93
parents a95ee7ad 8a7f0596
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ from cert.py_acl_manager import PyAclManager
from cert.truth import assertThat
import bluetooth_packets_python3 as bt_packets
from bluetooth_packets_python3 import l2cap_packets
from bluetooth_packets_python3 import RawBuilder
from bluetooth_packets_python3.l2cap_packets import CommandCode
from bluetooth_packets_python3.l2cap_packets import Final
from bluetooth_packets_python3.l2cap_packets import SegmentationAndReassembly
@@ -226,6 +227,28 @@ class CertL2cap(Closable, IHasBehaviors):

        return channel

    def verify_and_respond_open_channel_from_remote_and_send_config_req(self, psm=0x33):
        """
        Verify a connection request, and send a combo packet of connection response and configuration request
        """
        request = L2capCaptures.ConnectionRequest(psm)
        assertThat(self.control_channel).emits(request)

        sid = request.get().GetIdentifier()
        dcid = request.get().GetSourceCid()
        scid = dcid
        channel = CertL2capChannel(self._device, scid, dcid, self._get_acl_stream(), self._acl, self.control_channel)
        self.scid_to_channel[scid] = channel

        # Connection response and config request combo packet
        conn_rsp_and_config_req = RawBuilder([
            0x03, sid, 0x08, 0x00, dcid, 0x00, dcid, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, sid + 1, 0x04, 0x00, dcid,
            0x00, 0x00, 0x00
        ])
        self.control_channel.send(conn_rsp_and_config_req)

        return channel

    # prefer to use channel abstraction instead, if at all possible
    def send_acl(self, packet):
        self._acl.send(packet.Serialize())
+14 −0
Original line number Diff line number Diff line
@@ -224,6 +224,20 @@ class L2capTest(GdBaseTestClass):
        assertThat(self.cert_l2cap.get_control_channel()).emitsNone(L2capMatchers.ConfigurationResponse())
        # TODO: Verify that IUT sends disconnect request (not mandated)

    @metadata(pts_test_id="L2CAP/COS/CED/BV-09-C", pts_test_name="Receive Multi-Command Packet")
    def test_receive_multi_command_packet(self):
        """
        Verify that the IUT is able to receive more than one signaling command in one L2CAP
        packet.
        """
        self._setup_link_from_cert()

        psm = 0x33
        self.dut_l2cap.connect_dynamic_channel_to_cert(psm)
        self.cert_l2cap.verify_and_respond_open_channel_from_remote_and_send_config_req(psm)

        assertThat(self.cert_l2cap.get_control_channel()).emits(L2capMatchers.ConfigurationResponse())

    @metadata(pts_test_id="L2CAP/COS/CED/BV-11-C", pts_test_name="Configure MTU size")
    def test_configure_mtu_size(self):
        """
+23 −1
Original line number Diff line number Diff line
@@ -32,6 +32,22 @@ namespace classic {
namespace internal {
static constexpr auto kTimeout = std::chrono::seconds(3);

static std::vector<ControlView> GetCommandsFromPacketView(PacketView<kLittleEndian> packet) {
  size_t curr = 0;
  size_t end = packet.size();
  std::vector<ControlView> result;
  while (curr < end) {
    auto sub_view = packet.GetLittleEndianSubview(curr, end);
    auto control = ControlView::Create(sub_view);
    if (!control.IsValid()) {
      return {};
    }
    result.push_back(control);
    curr += 1 + 1 + 2 + control.GetPayload().size();
  }
  return result;
}

ClassicSignallingManager::ClassicSignallingManager(os::Handler* handler, Link* link,
                                                   l2cap::internal::DataPipelineManager* data_pipeline_manager,
                                                   DynamicChannelServiceManagerImpl* dynamic_service_manager,
@@ -678,7 +694,13 @@ void ClassicSignallingManager::OnInformationResponse(SignalId signal_id, const I

void ClassicSignallingManager::on_incoming_packet() {
  auto packet = signalling_channel_->GetQueueUpEnd()->TryDequeue();
  ControlView control_packet_view = ControlView::Create(*packet);
  auto command_list = GetCommandsFromPacketView(*packet);
  for (auto& command : command_list) {
    handle_one_command(command);
  }
}

void ClassicSignallingManager::handle_one_command(ControlView control_packet_view) {
  if (!control_packet_view.IsValid()) {
    LOG_WARN("Invalid signalling packet received");
    return;
+1 −0
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ class ClassicSignallingManager {

 private:
  void on_incoming_packet();
  void handle_one_command(ControlView control_view);
  void send_connection_response(SignalId signal_id, Cid remote_cid, Cid local_cid, ConnectionResponseResult result,
                                ConnectionResponseStatus status);
  void on_command_timeout();