예제 #1
0
 def test_multiple_channels_with_interleaved_data_streams(self):
     """
     Verify that an IUT can create multiple channels and receives data streams on the channels when the streams are interleaved.
     """
     self._setup_link_from_cert()
     (dut_channel_x,
      cert_channel_x) = self._open_channel_from_cert(signal_id=1,
                                                     scid=0x0103,
                                                     psm=0x33)
     (dut_channel_y,
      cert_channel_y) = self._open_channel_from_cert(signal_id=2,
                                                     scid=0x0105,
                                                     psm=0x35)
     (dut_channel_z,
      cert_channel_z) = self._open_channel_from_cert(signal_id=3,
                                                     scid=0x0107,
                                                     psm=0x37)
     cert_channel_y.send_first_le_i_frame(4, SAMPLE_PACKET)
     cert_channel_z.send_first_le_i_frame(4, SAMPLE_PACKET)
     cert_channel_y.send_first_le_i_frame(4, SAMPLE_PACKET)
     cert_channel_z.send_first_le_i_frame(4, SAMPLE_PACKET)
     cert_channel_y.send_first_le_i_frame(4, SAMPLE_PACKET)
     # TODO: We should assert two events in order, but it got stuck
     assertThat(dut_channel_y).emits(
         L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'),
         at_least_times=3)
     assertThat(dut_channel_z).emits(
         L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'),
         L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17')).inOrder()
     cert_channel_z.send_first_le_i_frame(4, SAMPLE_PACKET)
     assertThat(dut_channel_z).emits(
         L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'))
예제 #2
0
    def test_receiving_scid_over_bredr_and_le(self):
        """
        Test that the L2CAP entity can receive the same SCID in L2CAP connect requests on both the
        BR/EDR and LE links.
        """
        self._setup_acl_link_from_cert()
        # TODO: We should let LE use public address, same as classic link.
        # TODO: Update AclManager::impl::create_le_connection
        self._setup_le_link_from_cert()
        (dut_channel, cert_channel) = self._open_channel_from_cert(0x33, 0x70)
        (le_dut_channel,
         le_cert_channel) = self._open_le_coc_from_cert(0x35, 0x70)

        dut_channel.send(b'abc')
        assertThat(cert_channel).emits(L2capMatchers.Data(b'abc'))

        le_dut_channel.send(b'hello')
        assertThat(le_cert_channel).emits(
            L2capMatchers.FirstLeIFrame(b'hello', sdu_size=5))

        le_cert_channel.send_first_le_i_frame(4, SAMPLE_PACKET)
        assertThat(le_dut_channel).emits(
            L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'))

        cert_channel.disconnect_and_verify()
        le_cert_channel.disconnect_and_verify()
예제 #3
0
    def test_handle_duplicate_srej(self):
        """
        L2CAP/ERM/BI-03-C [Handle Duplicate S-Frame [SREJ]]
        Verify the IUT will only retransmit the requested I-frame once after receiving a duplicate SREJ.
        """
        self._setup_link_from_cert()
        self.cert_l2cap.turn_on_ertm()

        (dut_channel, cert_channel) = self._open_channel(scid=0x41,
                                                         psm=0x33,
                                                         use_ertm=True)

        dut_channel.send(b'abc')
        dut_channel.send(b'abc')
        assertThat(cert_channel).emits(
            L2capMatchers.IFrame(tx_seq=0), L2capMatchers.IFrame(tx_seq=1),
            L2capMatchers.SFrame(p=Poll.POLL)).inOrder()

        cert_channel.send_s_frame(req_seq=0,
                                  s=SupervisoryFunction.SELECT_REJECT)
        assertThat(cert_channel).emitsNone(timeout=timedelta(seconds=0.5))

        cert_channel.send_s_frame(req_seq=0,
                                  s=SupervisoryFunction.SELECT_REJECT,
                                  f=Final.POLL_RESPONSE)
        assertThat(cert_channel).emits(L2capMatchers.IFrame(tx_seq=0))
예제 #4
0
    def test_handle_rej_and_i_frame_with_f_set(self):
        """
        L2CAP/ERM/BI-05-C [Handle receipt of S-Frame [REJ] and I-Frame [F=1] that Both Require Retransmission of the Same I-Frames]
        Verify the IUT will only retransmit the requested I-frames once after receiving an S-frame [REJ]
        followed by an I-frame with the Final bit set that indicates the same I-frames should be retransmitted.
        """
        self._setup_link_from_cert()
        self.cert_l2cap.turn_on_ertm()

        (dut_channel, cert_channel) = self._open_channel(scid=0x41,
                                                         psm=0x33,
                                                         use_ertm=True)

        dut_channel.send(b'abc')
        dut_channel.send(b'abc')
        assertThat(cert_channel).emits(
            L2capMatchers.IFrame(tx_seq=0), L2capMatchers.IFrame(tx_seq=1),
            L2capMatchers.SFrame(p=l2cap_packets.Poll.POLL)).inOrder()

        # Send SREJ with F not set
        cert_channel.send_s_frame(req_seq=0,
                                  s=SupervisoryFunction.SELECT_REJECT)
        assertThat(cert_channel).emitsNone(timeout=timedelta(seconds=0.5))

        cert_channel.send_i_frame(tx_seq=0,
                                  req_seq=0,
                                  f=Final.POLL_RESPONSE,
                                  payload=SAMPLE_PACKET)

        assertThat(cert_channel).emits(L2capMatchers.IFrame(tx_seq=0))
        assertThat(cert_channel).emits(L2capMatchers.IFrame(tx_seq=1))
예제 #5
0
    def test_receive_i_frame_final_bit_set(self):
        """
        L2CAP/ERM/BV-19-C [Receive I-Frame Final Bit = 1]
        Verify the IUT will retransmit any previously sent I-frames unacknowledged by receipt of an I-frame
        with the final bit set.
        """
        self._setup_link_from_cert()
        self.cert_l2cap.turn_on_ertm()

        (dut_channel, cert_channel) = self._open_channel(scid=0x41,
                                                         psm=0x33,
                                                         use_ertm=True)

        dut_channel.send(b'abc')

        # TODO: Always use their retransmission timeout value
        time.sleep(2)
        assertThat(cert_channel).emits(L2capMatchers.SFrame(p=Poll.POLL))

        cert_channel.send_i_frame(tx_seq=0,
                                  req_seq=0,
                                  f=Final.POLL_RESPONSE,
                                  payload=SAMPLE_PACKET)

        assertThat(cert_channel).emits(L2capMatchers.IFrame(tx_seq=0))
예제 #6
0
    def test_sent_rej_lost(self):
        """
        L2CAP/ERM/BI-01-C [S-Frame [REJ] Lost or Corrupted]
        Verify the IUT can handle receipt of an S-=frame [RR] Poll = 1 if the S-frame [REJ] sent from the IUT
        is lost.
        """
        self._setup_link_from_cert()
        self.cert_l2cap.turn_on_ertm(tx_window_size=5)
        ertm_tx_window_size = 5

        (dut_channel, cert_channel) = self._open_channel(scid=0x41,
                                                         psm=0x41,
                                                         use_ertm=True)

        cert_channel.send_i_frame(tx_seq=0, req_seq=0, payload=SAMPLE_PACKET)
        assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=1))

        cert_channel.send_i_frame(tx_seq=ertm_tx_window_size - 1,
                                  req_seq=0,
                                  payload=SAMPLE_PACKET)
        assertThat(cert_channel).emits(
            L2capMatchers.SFrame(s=SupervisoryFunction.REJECT))

        cert_channel.send_s_frame(req_seq=0, p=Poll.POLL)

        assertThat(cert_channel).emits(
            L2capMatchers.SFrame(req_seq=1,
                                 f=l2cap_packets.Final.POLL_RESPONSE))
        for i in range(1, ertm_tx_window_size):
            cert_channel.send_i_frame(tx_seq=i,
                                      req_seq=0,
                                      payload=SAMPLE_PACKET)
            assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=i + 1))
예제 #7
0
    def test_receive_i_frames(self):
        """
        L2CAP/ERM/BV-02-C [Receive I-Frames]
        Verify the IUT can receive in-sequence valid I-frames and deliver L2CAP SDUs to the Upper Tester
        """
        self._setup_link_from_cert()
        self.cert_l2cap.turn_on_ertm()

        (dut_channel, cert_channel) = self._open_channel(scid=0x41,
                                                         psm=0x33,
                                                         use_ertm=True)

        for i in range(3):
            cert_channel.send_i_frame(tx_seq=i,
                                      req_seq=0,
                                      payload=SAMPLE_PACKET)
            assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=i + 1))

        cert_channel.send_i_frame(tx_seq=3,
                                  req_seq=0,
                                  sar=SegmentationAndReassembly.START,
                                  payload=SAMPLE_PACKET)
        assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=4))

        cert_channel.send_i_frame(tx_seq=4,
                                  req_seq=0,
                                  sar=SegmentationAndReassembly.CONTINUATION,
                                  payload=SAMPLE_PACKET)
        assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=5))

        cert_channel.send_i_frame(tx_seq=5,
                                  req_seq=0,
                                  sar=SegmentationAndReassembly.END,
                                  payload=SAMPLE_PACKET)
        assertThat(cert_channel).emits(L2capMatchers.SFrame(req_seq=6))
예제 #8
0
    def test_resume_transmitting_when_acknowledge_previously_sent(self):
        """
        L2CAP/ERM/BV-06-C [Resume Transmitting I-Frames when an I-Frame is Received]
        Verify the IUT will cease transmission of I-frames when the negotiated TxWindow is full. Verify the
        IUT will resume transmission of I-frames when an I-frame is received that acknowledges previously
        sent I-frames.
        """
        self._setup_link_from_cert()
        self.cert_l2cap.turn_on_ertm(tx_window_size=1)

        (dut_channel, cert_channel) = self._open_channel(scid=0x41,
                                                         psm=0x33,
                                                         use_ertm=True)

        dut_channel.send(b'abc')
        dut_channel.send(b'def')

        assertThat(cert_channel).emits(
            L2capMatchers.IFrame(tx_seq=0, payload=b'abc'))
        # TODO: If 1 second is greater than their retransmit timeout, use a smaller timeout
        assertThat(cert_channel).emitsNone(L2capMatchers.IFrame(
            tx_seq=1, payload=b'abc'),
                                           timeout=timedelta(seconds=1))

        cert_channel.send_i_frame(tx_seq=0, req_seq=1, payload=SAMPLE_PACKET)

        assertThat(cert_channel).emits(
            L2capMatchers.IFrame(tx_seq=1, payload=b'def'))

        cert_channel.send_i_frame(tx_seq=1, req_seq=2, payload=SAMPLE_PACKET)
예제 #9
0
    def test_transmit_i_frames(self):
        """
        L2CAP/ERM/BV-01-C [Transmit I-frames]
        """
        self._setup_link_from_cert()
        self.cert_l2cap.turn_on_ertm()

        (dut_channel, cert_channel) = self._open_channel(scid=0x41,
                                                         psm=0x33,
                                                         use_ertm=True)

        dut_channel.send(b'abc')
        assertThat(cert_channel).emits(
            L2capMatchers.IFrame(tx_seq=0, payload=b"abc"))

        # Assemble a sample packet. TODO: Use RawBuilder
        SAMPLE_PACKET = l2cap_packets.CommandRejectNotUnderstoodBuilder(1)

        # todo: verify packet received?
        cert_channel.send_i_frame(tx_seq=0, req_seq=1, payload=SAMPLE_PACKET)

        dut_channel.send(b'abc')
        assertThat(cert_channel).emits(
            L2capMatchers.IFrame(tx_seq=1, payload=b"abc"))

        cert_channel.send_i_frame(tx_seq=1, req_seq=2, payload=SAMPLE_PACKET)

        dut_channel.send(b'abc')
        assertThat(cert_channel).emits(L2capMatchers.PartialData(b"abc"))

        cert_channel.send_i_frame(tx_seq=2, req_seq=3, payload=SAMPLE_PACKET)
예제 #10
0
    def _open_channel(self,
                      signal_id=1,
                      scid=0x0101,
                      psm=0x33,
                      use_ertm=False):
        result = self._open_unvalidated_channel(signal_id, scid, psm, use_ertm)

        assertThat(self.cert_l2cap.get_control_channel()).emits(
            L2capMatchers.ConfigurationResponse(),
            L2capMatchers.ConfigurationRequest()).inAnyOrder()

        return result
예제 #11
0
 def test_segmentation(self):
     """
     Verify that the IUT can send data segments which are larger than the LE frame size.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_cert(mtu=1000, mps=102)
     dut_channel.send(b'hello' * 20 + b'world')
     # The first LeInformation packet contains 2 bytes of SDU size.
     # The packet is divided into first 100 bytes from 'hellohello....'
     # and remaining 5 bytes 'world'
     assertThat(cert_channel).emits(
         L2capMatchers.FirstLeIFrame(b'hello' * 20, sdu_size=105), L2capMatchers.Data(b'world')).inOrder()
예제 #12
0
    def test_retry_config_after_rejection(self):
        """
        L2CAP/COS/CFD/BV-02-C
        """
        self._setup_link_from_cert()

        self.cert_l2cap.reply_with_unacceptable_parameters()

        self._open_unvalidated_channel(scid=0x41, psm=0x33)

        assertThat(self.cert_l2cap.get_control_channel()).emits(
            L2capMatchers.ConfigurationResponse(),
            L2capMatchers.ConfigurationRequest(),
            L2capMatchers.ConfigurationRequest()).inAnyOrder()
예제 #13
0
 def test_credit_exchange_receiving_incremental_credits(self):
     """
     Verify the IUT handles flow control correctly, by handling the LE Flow Control Credit sent by the peer.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_cert(initial_credit=0)
     for _ in range(4):
         dut_channel.send(b'hello')
     cert_channel.send_credits(1)
     assertThat(cert_channel).emits(L2capMatchers.FirstLeIFrame(b'hello', sdu_size=5))
     cert_channel.send_credits(1)
     assertThat(cert_channel).emits(L2capMatchers.FirstLeIFrame(b'hello', sdu_size=5))
     cert_channel.send_credits(2)
     assertThat(cert_channel).emits(
         L2capMatchers.FirstLeIFrame(b'hello', sdu_size=5), L2capMatchers.FirstLeIFrame(b'hello', sdu_size=5))
예제 #14
0
    def test_connect_dynamic_channel_and_send_data(self):
        self._setup_link_from_cert()

        (dut_channel, cert_channel) = self._open_channel(scid=0x41, psm=0x33)

        dut_channel.send(b'abc')
        assertThat(cert_channel).emits(L2capMatchers.Data(b'abc'))
예제 #15
0
 def __init__(self, device, cid, l2cap_stream):
     self._device = device
     self._cid = cid
     self._le_l2cap_stream = l2cap_stream
     self._our_le_l2cap_view = FilteringEventStream(
         self._le_l2cap_stream,
         L2capMatchers.PacketPayloadWithMatchingCid(self._cid))
예제 #16
0
 def test_fixed_channel_receive(self):
     self.dut_l2cap.enable_fixed_channel(4)
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_fixed_channel(4)
     cert_channel.send(SAMPLE_PACKET)
     assertThat(dut_channel).emits(
         L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'))
예제 #17
0
 def test_command_reject_reserved_pdu_codes(self):
     """
     Verify that an IUT receiving a PDU with a reserved command code sends a command reject.
     """
     self._setup_link_from_cert()
     self.cert_l2cap.get_control_channel().send(l2cap_packets.MoveChannelRequestBuilder(2, 0, 0))
     assertThat(self.cert_l2cap.get_control_channel()).emits(L2capMatchers.LeCommandReject())
예제 #18
0
 def test_data_receiving_dut_is_central(self):
     """
     L2CAP/COS/CFC/BV-04-C
     """
     (dut_channel, cert_channel) = self._set_link_from_dut_and_open_channel()
     cert_channel.send_first_le_i_frame(4, SAMPLE_PACKET)
     assertThat(dut_channel).emits(L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'))
예제 #19
0
 def test_no_segmentation_dut_is_central(self):
     """
     L2CAP/COS/CFC/BV-02-C
     """
     (dut_channel, cert_channel) = self._set_link_from_dut_and_open_channel()
     dut_channel.send(b'hello' * 40)
     assertThat(cert_channel).emits(L2capMatchers.FirstLeIFrame(b'hello' * 40, sdu_size=200))
예제 #20
0
 def __init__(self, device, psm, l2cap_stream):
     self._device = device
     self._psm = psm
     self._le_l2cap_stream = l2cap_stream
     self._our_le_l2cap_view = FilteringEventStream(
         self._le_l2cap_stream,
         L2capMatchers.PacketPayloadWithMatchingPsm(self._psm))
예제 #21
0
 def test_no_segmentation(self):
     """
     Verify that the IUT can send data segments which do not require segmentation.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_cert(mtu=1000, mps=202)
     dut_channel.send(b'hello' * 40)
     assertThat(cert_channel).emits(L2capMatchers.FirstLeIFrame(b'hello' * 40, sdu_size=200))
예제 #22
0
 def test_reject_connection_parameter_update_request(self):
     """
     Verify that the IUT is able to reject a request for connection parameter update in peripheral mode.
     """
     self._setup_link_from_cert()
     self.cert_l2cap.get_control_channel().send(
         l2cap_packets.ConnectionParameterUpdateRequestBuilder(2, 0x10, 0x10, 0x0a, 0x64))
     assertThat(self.cert_l2cap.get_control_channel()).emits(L2capMatchers.LeCommandReject())
예제 #23
0
 def test_credit_based_connection_response_on_supported_le_psm(self):
     """
     Verify that an IUT receiving a valid LE Credit Based Connection Request from a peer will send an LE Credit Based Connection Response and establish the channel.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_cert()
     dut_channel.send(b'hello')
     assertThat(cert_channel).emits(L2capMatchers.FirstLeIFrame(b'hello', sdu_size=5))
예제 #24
0
 def test_le_credit_based_connection_request_on_supported_le_psm(self):
     """
     Verify that an IUT sending an LE Credit Based Connection Request to a peer will establish the channel upon receiving the LE Credit Based Connection Response.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_dut()
     cert_channel.send_first_le_i_frame(4, SAMPLE_PACKET)
     assertThat(dut_channel).emits(L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'))
예제 #25
0
 def test_data_receiving(self):
     """
     Verify that the IUT can receive unsegmented data correctly.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_cert()
     cert_channel.send_first_le_i_frame(4, SAMPLE_PACKET)
     assertThat(dut_channel).emits(L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17'))
예제 #26
0
    def disconnect_and_verify(self):
        assertThat(self._scid).isNotEqualTo(1)
        self._control_channel.send(
            l2cap_packets.LeDisconnectionRequestBuilder(
                1, self._dcid, self._scid))

        assertThat(self._control_channel).emits(
            L2capMatchers.LeDisconnectionResponse(self._scid, self._dcid))
예제 #27
0
 def test_reject_unknown_command_in_le_sigling_channel(self):
     """
     Verify that the IUT is able to reject unknown command.
     """
     self._setup_link_from_cert()
     self.cert_l2cap.get_control_channel().send(
         l2cap_packets.InformationRequestBuilder(
             2, l2cap_packets.InformationRequestInfoType.EXTENDED_FEATURES_SUPPORTED))
     assertThat(self.cert_l2cap.get_control_channel()).emits(L2capMatchers.LeCommandReject())
예제 #28
0
 def test_request_refused_due_to_source_cid_already_allocated_responder(self):
     """
     Verify that an IUT receiving an LE Credit Based Connection Request for a second channel will refuse the connection with result "0x000A - Connection refused – Source CID already allocated" if it receives a Source CID which is already in use.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_cert(psm=0x33, scid=0x0101)
     self.dut_l2cap.register_coc(self.cert_address, psm=0x35)
     self.cert_l2cap.get_control_channel().send(
         l2cap_packets.LeCreditBasedConnectionRequestBuilder(2, 0x35, 0x0101, 1000, 1000, 1000))
     assertThat(self.cert_l2cap.get_control_channel()).emits(L2capMatchers.CreditBasedConnectionResponseUsedCid())
예제 #29
0
 def test_credit_based_connection_request_unsupported_le_psm(self):
     """
     Verify that an IUT receiving an LE Credit Based Connection Request on an unsupported LE_PSM will respond with an LE Credit Based Connection Response refusing the connection.
     """
     self._setup_link_from_cert()
     self.cert_l2cap.get_control_channel().send(
         l2cap_packets.LeCreditBasedConnectionRequestBuilder(1, 0x34, 0x0101, 2000, 1000, 1000))
     assertThat(self.cert_l2cap.get_control_channel()).emits(
         L2capMatchers.CreditBasedConnectionResponse(
             result=LeCreditBasedConnectionResponseResult.LE_PSM_NOT_SUPPORTED))
예제 #30
0
 def test_reassembling(self):
     """
     Verify that the IUT can correctly reassemble data received from the Lower Tester which is greater than the IUT LE-frame size.
     """
     self._setup_link_from_cert()
     (dut_channel, cert_channel) = self._open_channel_from_cert()
     sdu_size_for_two_sample_packet = 8
     cert_channel.send_first_le_i_frame(sdu_size_for_two_sample_packet, SAMPLE_PACKET)
     cert_channel.send(SAMPLE_PACKET)
     assertThat(dut_channel).emits(L2capMatchers.PacketPayloadRawData(b'\x19\x26\x08\x17' * 2))