def run_precondition(self, ntb_format):
        """
        Runs all the precondition sequences for data transfer tests.

        @param ntb_format: Whether to send/receive an NTB16 or NTB32 frame.
                Possible values: NTB_FORMAT_16, NTB_FORMAT_32 (mbim_constants)
        @returns tuple of (desc_sequence, open_sequence, connect_sequence) where,
                desc_sequence - Handle to run the get descriptor sequence.
                open_sequence - Handle to run the open sequence.
                connect_sequence - Handle to run the connect sequence.

        """
        desc_sequence = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context)
        descriptors = desc_sequence.run()
        self.device_context.update_descriptor_cache(descriptors)
        open_sequence = mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context)
        open_sequence.run(ntb_format=ntb_format)
        connect_seq = connect_sequence.ConnectSequence(self.device_context)
        connect_seq.run()

        # Devices may not support SetNtbFormat(), so fail the NTB32 tests on
        # such devices.
        if ((ntb_format == mbim_constants.NTB_FORMAT_32)
                and (self.device_context.current_ntb_format != ntb_format)):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceFrameworkError,
                'Device does not support NTB 32 format.')

        return (desc_sequence, open_sequence, connect_seq)
    def run_internal(self):
        """ Run the CM_01 test. """
        # Precondition.
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)

        # Step 1
        open_message, response_message = (
            mbim_open_generic_sequence.MBIMOpenGenericSequence(
                self.device_context).run())
Ejemplo n.º 3
0
    def run_internal(self):
        """ Run CM_10 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        # Step 1
        close_message, response_message = mbim_close_sequence.MBIMCloseSequence(
            self.device_context).run()
Ejemplo n.º 4
0
    def run_internal(self):
        """ Run CM_06 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        # Step 1
        _, response_message = (
            mbim_cid_device_caps_sequence.MBIMCIDDeviceCapsSequence(
                self.device_context).run())
        if response_message.status_codes != mbim_constants.MBIM_STATUS_SUCCESS:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.4.5#1')
    def run_internal(self):
        """ Run the CM_02 test. """
        # Precondition.
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)

        # Step 1
        _, response_message = (
            mbim_open_generic_sequence.MBIMOpenGenericSequence(
                self.device_context).run())

        # Validate message length of response to MBIM_OPEN_MESSAGE.
        if response_message.message_length < 0x0C:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.1#2')
Ejemplo n.º 6
0
    def run_internal(self):
        """ Run CM_04 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        # Step 1
        command_message, response_message = (
            mbim_cid_device_caps_sequence.MBIMCIDDeviceCapsSequence(
                self.device_context).run())
        # Validate |transaction_id| in the response to MBIM_COMMAND_MSG.
        if response_message.transaction_id != command_message.transaction_id:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.4.3')
    def run_internal(self):
        """ Run CM_15 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
                self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        open_sequence = mbim_open_generic_sequence.MBIMOpenGenericSequence(
                self.device_context)
        open_sequence.run(max_control_transfer_size=64)

        # Step 1
        caps_sequence = mbim_cid_device_caps_sequence.MBIMCIDDeviceCapsSequence(
                self.device_context)
        _, response_message = caps_sequence.run()
        if not isinstance(response_message,
                          mbim_command_message.MBIMDeviceCapsInfo):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.2')
Ejemplo n.º 8
0
    def run_internal(self):
        """ Run CM_03 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        # Step 1
        _, response_message = (
            mbim_open_generic_sequence.MBIMOpenGenericSequence(
                self.device_context).run())

        # Validate function's behaviour for an unsynchronized MBIM_OPEN_MSG.
        if response_message.message_type == mbim_constants.MBIM_CLOSE_DONE:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.3.1#1')
Ejemplo n.º 9
0
    def run_internal(self):
        """ Run CM_09 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        # Step 1
        _, _, notifications = (connect_sequence.ConnectSequence(
            self.device_context).run())

        # Step 2
        for notification in notifications:
            if notification.transaction_id != 0:
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceAssertionError, 'mbim1.0:9.1#1')
Ejemplo n.º 10
0
    def run_internal(self):
        """ Run CM_14 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()
        mbim_close_sequence.MBIMCloseSequence(self.device_context).run()

        # Step 1
        _, response_message, _ = (connect_sequence.ConnectSequence(
            self.device_context).run(raise_exception_on_failure=False))

        # Step 2
        if ((response_message.message_type !=
             mbim_constants.MBIM_FUNCTION_ERROR_MSG)
                or (response_message.message_length != 16)):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.3.4#2')
Ejemplo n.º 11
0
    def run_internal(self):
        """ Run ERR_04 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        open_sequence = mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context)
        open_sequence.run(max_control_transfer_size=64)

        # Step 1
        request_message, response_message, _ = (
            connect_sequence.ConnectSequence(self.device_context).run(
                introduce_error_in_packets_order=[1, 0, 2],
                raise_exception_on_failure=False))

        # Step 2
        if ((response_message.transaction_id != request_message.transaction_id)
                or (response_message.message_type
                    == mbim_constants.MBIM_COMMAND_DONE)):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.3.4.2#3')
Ejemplo n.º 12
0
    def run_internal(self):
        """ Run CM_08 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        # Step 1
        device_context = self.device_context
        descriptor_cache = device_context.descriptor_cache
        command_message = mbim_message_request.MBIMCommand(
            device_service_id=mbim_constants.UUID_BASIC_CONNECT.bytes,
            cid=mbim_constants.MBIM_CID_RADIO_STATE,
            command_type=mbim_constants.COMMAND_TYPE_SET,
            information_buffer_length=4,
            payload_buffer=array.array('B', struct.pack('I', 2)))
        packets = mbim_message_request.generate_request_packets(
            command_message, device_context.max_control_transfer_size)
        channel = mbim_channel.MBIMChannel(
            device_context._device,
            descriptor_cache.mbim_communication_interface.bInterfaceNumber,
            descriptor_cache.interrupt_endpoint.bEndpointAddress,
            device_context.max_control_transfer_size)
        response_packets = channel.bidirectional_transaction(*packets)
        channel.close()

        # Step 2
        response_message = mbim_message_response.parse_response_packets(
            response_packets)

        # Step 3
        if ((response_message.message_type != mbim_constants.MBIM_COMMAND_DONE)
                or (response_message.status_codes
                    == mbim_constants.MBIM_STATUS_SUCCESS)
                or response_message.information_buffer_length != 0):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.4.5#3')
Ejemplo n.º 13
0
    def run_internal(self):
        """ Run CM_07 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        # Step 1
        # 255 is an unsupported CID.
        device_context = self.device_context
        descriptor_cache = device_context.descriptor_cache
        command_message = mbim_message_request.MBIMCommand(
            device_service_id=mbim_constants.UUID_BASIC_CONNECT.bytes,
            cid=255,
            command_type=mbim_constants.COMMAND_TYPE_QUERY,
            information_buffer_length=0)
        packets = mbim_message_request.generate_request_packets(
            command_message, device_context.max_control_transfer_size)
        channel = mbim_channel.MBIMChannel(
            device_context._device,
            descriptor_cache.mbim_communication_interface.bInterfaceNumber,
            descriptor_cache.interrupt_endpoint.bEndpointAddress,
            device_context.max_control_transfer_size)
        response_packets = channel.bidirectional_transaction(*packets)
        channel.close()

        # Step 2
        response_message = mbim_message_response.parse_response_packets(
            response_packets)

        # Step 3
        if (response_message.message_type != mbim_constants.MBIM_COMMAND_DONE
                or (response_message.status_codes !=
                    mbim_constants.MBIM_STATUS_NO_DEVICE_SUPPORT)):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.4.5#2')
Ejemplo n.º 14
0
    def run_internal(self):
        """ Run ERR_02 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        open_sequence = mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context)
        open_sequence.run(max_control_transfer_size=64)

        # Step 1
        request_message, response_message, _ = (
            connect_sequence.ConnectSequence(self.device_context).run(
                introduce_error_in_packets_order=[1, 0, 2],
                raise_exception_on_failure=False))

        # Step 2
        if ((response_message.message_type !=
             mbim_constants.MBIM_FUNCTION_ERROR_MSG)
                or (response_message.error_status_code !=
                    mbim_constants.MBIM_ERROR_FRAGMENT_OUT_OF_SEQUENCE)):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.3.4#3')
Ejemplo n.º 15
0
    def run_internal(self):
        """ Run ERR_05 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
                self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        open_sequence = mbim_open_generic_sequence.MBIMOpenGenericSequence(
                self.device_context)
        open_sequence.run(max_control_transfer_size=64)

        # Step 1
        request_message, first_response_message, notifications = (
                connect_sequence.ConnectSequence(self.device_context).run(
                        introduce_error_in_packets_order=[1, 1],
                        raise_exception_on_failure=False))

        if len(notifications) > 1:
            mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceTestError,
                    'Not expecting more than 1 pending response.')
        second_response_message = notifications[0]

        # Step 2
        if (((first_response_message.transaction_id !=
              request_message.transaction_id) or
             (first_response_message.message_type !=
              mbim_constants.MBIM_FUNCTION_ERROR_MSG) or
             (first_response_message.error_status_code !=
              mbim_constants.MBIM_ERROR_FRAGMENT_OUT_OF_SEQUENCE)) or
            ((second_response_message.transaction_id !=
              request_message.transaction_id) or
             (second_response_message.message_type !=
              mbim_constants.MBIM_FUNCTION_ERROR_MSG) or
             (second_response_message.error_status_code !=
              mbim_constants.MBIM_ERROR_FRAGMENT_OUT_OF_SEQUENCE))):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:9.3.4.2#4')
Ejemplo n.º 16
0
    def run_internal(self):
        """ Run the CM_01 test. """
        # Precondition.
        desc_sequence = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context)
        descriptors = desc_sequence.run()
        self.device_context.update_descriptor_cache(descriptors)
        open_sequence = mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context)
        open_sequence.run()
        caps_sequence = mbim_cid_device_caps_sequence.MBIMCIDDeviceCapsSequence(
            self.device_context)
        _, caps_response = caps_sequence.run()

        # Step1
        if (caps_response.cellular_class
                & mbim_constants.CELLULAR_CLASS_MASK_CDMA):
            if not ((caps_response.control_caps
                     & mbim_constants.CTRL_CAPS_MASK_CDMA_MOBILE_IP) or
                    (caps_response.control_caps
                     & mbim_constants.CTRL_CAPS_MASK_CDMA_SIMPLE_IP)):
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceAssertionError,
                    'mbim1.0:10.5.1.3#1')
    def run_internal(self):
        """ Run the DES_01 test. """
        # Precondition.
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()

        # Test step 1
        # Get ncm communication interface and mbim communication interface.
        interfaces = usb_descriptors.filter_descriptors(
            usb_descriptors.InterfaceDescriptor, descriptors)

        ncm_communication_interfaces = (
            usb_descriptors.filter_interface_descriptors(
                interfaces,
                usb_descriptors.NCM_MBIM_COMMUNICATION_INTERFACE_NCM))

        mbim_communication_interfaces = (
            usb_descriptors.filter_interface_descriptors(
                interfaces,
                usb_descriptors.NCM_MBIM_COMMUNICATION_INTERFACE_MBIM))

        # If we don't find both NCM and MBIM interfaces, then we should bail
        # out of this test
        if (not ncm_communication_interfaces
                or not mbim_communication_interfaces):
            return

        if len(ncm_communication_interfaces) != 1:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.1#2')
        ncm_communication_interface = ncm_communication_interfaces[0]

        if len(mbim_communication_interfaces) != 1:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.1#3')
        mbim_communication_interface = mbim_communication_interfaces[0]

        if (ncm_communication_interface.bInterfaceNumber !=
                mbim_communication_interface.bInterfaceNumber):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.1#1')

        # Test step 2
        if (ncm_communication_interface.index >
                mbim_communication_interface.index):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Alternate setting 1 of the interface must appear after'
                'alternate setting 0 of the interface.')

        # Test step 3
        # Get header functional descriptor, union functinoal descriptor,
        # MBIM functinoal descriptor and MBIM extended functional
        # descriptor from |ncm_communication_interface|[0].
        ncm_communication_interface_bundle = (
            usb_descriptors.get_descriptor_bundle(descriptors,
                                                  ncm_communication_interface))

        header_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.HeaderFunctionalDescriptor,
            ncm_communication_interface_bundle)
        union_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.UnionFunctionalDescriptor,
            ncm_communication_interface_bundle)
        mbim_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.MBIMFunctionalDescriptor,
            ncm_communication_interface_bundle)
        mbim_extended_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.MBIMExtendedFunctionalDescriptor,
            ncm_communication_interface_bundle)
        if not (header_descriptors and union_descriptors and mbim_descriptors):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#2')

        # Test step 4
        # Check header funcional descriptor.
        if usb_descriptors.has_distinct_descriptors(header_descriptors):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 unique header functional descriptor.')
        header_descriptor = header_descriptors[0]
        if not (header_descriptor.bDescriptorType == 0x24
                and header_descriptor.bDescriptorSubtype == 0x00
                and header_descriptor.bLength == 5
                and header_descriptor.bcdCDC >= 0x0120):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Header functional descriptor: wrong value(s)')

        # Test step 5
        # Check union functional descriptor.
        if usb_descriptors.has_distinct_descriptors(union_descriptors):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 unique union functional descriptor.')

        union_descriptor = union_descriptors[0]
        if union_descriptor.index < header_descriptor.index:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#3')
        # Get no data data interface.
        no_data_data_interfaces = usb_descriptors.filter_interface_descriptors(
            interfaces, usb_descriptors.NCM_MBIM_DATA_INTERFACE_NO_DATA)

        if len(no_data_data_interfaces) != 1:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#2')

        no_data_data_interface = no_data_data_interfaces[0]
        no_data_data_interface_bundle = usb_descriptors.get_descriptor_bundle(
            descriptors, no_data_data_interface)
        endpoint_descriptors = (usb_descriptors.filter_descriptors(
            usb_descriptors.EndpointDescriptor, no_data_data_interface_bundle))

        if endpoint_descriptors:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#4')

        # Get NCM data interface.
        ncm_data_interfaces = (usb_descriptors.filter_interface_descriptors(
            interfaces, usb_descriptors.NCM_MBIM_DATA_INTERFACE_NCM))

        if len(ncm_data_interfaces) != 1:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#2')
        ncm_data_interface = ncm_data_interfaces[0]
        if ncm_data_interface.bNumEndpoints != 2:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#4')
        ncm_data_interface_bundle = (usb_descriptors.get_descriptor_bundle(
            descriptors, ncm_data_interface))
        endpoint_descriptors = (usb_descriptors.filter_descriptors(
            usb_descriptors.EndpointDescriptor, ncm_data_interface_bundle))
        # Check endpoint descriptors in |ncm_data_interface_bundle|
        # There should be one bulk OUT and one bulk IN.
        if not usb_descriptors.has_bulk_in_and_bulk_out(endpoint_descriptors):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#4')

        # Get MBIM data interface.
        mbim_data_interfaces = usb_descriptors.filter_interface_descriptors(
            interfaces, usb_descriptors.NCM_MBIM_DATA_INTERFACE_MBIM)

        if len(mbim_data_interfaces) != 1:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#3')
        mbim_data_interface = mbim_data_interfaces[0]
        if mbim_data_interface.bNumEndpoints != 2:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#4')

        mbim_data_interface_bundle = (usb_descriptors.get_descriptor_bundle(
            descriptors, mbim_data_interface))
        endpoint_descriptors = (usb_descriptors.filter_descriptors(
            usb_descriptors.EndpointDescriptor, mbim_data_interface_bundle))
        # Check endpoint descriptors in |mbim_data_interface_bundle|
        # alternate setting 2. There should be one bulk OUT and one bulk IN.
        if not usb_descriptors.has_bulk_in_and_bulk_out(endpoint_descriptors):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#4')

        if not (no_data_data_interface.bInterfaceNumber ==
                ncm_data_interface.bInterfaceNumber ==
                mbim_data_interface.bInterfaceNumber):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:3.2.2.4#1')

        if not (union_descriptor.bLength == 5
                and union_descriptor.bControlInterface
                == (ncm_communication_interface.bInterfaceNumber)
                and union_descriptors.bSubordinateInterface0
                == (no_data_data_interface.bInterfaceNumber)):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#4')
Ejemplo n.º 18
0
    def run_internal(self):
        """ Run CM_05 test. """
        # Precondition
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()
        self.device_context.update_descriptor_cache(descriptors)
        mbim_open_generic_sequence.MBIMOpenGenericSequence(
            self.device_context).run()

        device_context = self.device_context
        descriptor_cache = device_context.descriptor_cache
        self.channel = mbim_channel.MBIMChannel(
            device_context._device,
            descriptor_cache.mbim_communication_interface.bInterfaceNumber,
            descriptor_cache.interrupt_endpoint.bEndpointAddress,
            device_context.max_control_transfer_size)

        # Step 1
        caps_command_message = mbim_command_message.MBIMDeviceCapsQuery()
        caps_packets = mbim_message_request.generate_request_packets(
            caps_command_message, device_context.max_control_transfer_size)
        self.caps_transaction_id = caps_command_message.transaction_id
        self.channel.unidirectional_transaction(*caps_packets)

        # Step 2
        services_command_message = (
            mbim_command_message.MBIMDeviceServicesQuery())
        services_packets = mbim_message_request.generate_request_packets(
            services_command_message, device_context.max_control_transfer_size)
        self.services_transaction_id = services_command_message.transaction_id
        self.channel.unidirectional_transaction(*services_packets)

        # Step 3
        utils.poll_for_condition(
            self._get_response_packets,
            timeout=5,
            exception=mbim_errors.MBIMComplianceChannelError(
                'Failed to retrieve the response packets to specific '
                'control messages.'))
        self.channel.close()

        caps_response_message = self.caps_response
        services_response_message = self.services_response
        is_caps_message_valid = isinstance(
            caps_response_message, mbim_command_message.MBIMDeviceCapsInfo)
        is_services_message_valid = isinstance(
            services_response_message,
            mbim_command_message.MBIMDeviceServicesInfo)
        if not ((is_caps_message_valid and is_services_message_valid) and
                (caps_response_message.transaction_id
                 == caps_command_message.transaction_id) and
                (caps_response_message.device_service_id
                 == caps_command_message.device_service_id)
                and caps_response_message.cid == caps_command_message.cid and
                (services_command_message.transaction_id
                 == services_response_message.transaction_id) and
                (services_command_message.device_service_id
                 == services_response_message.device_service_id) and
                services_command_message.cid == services_response_message.cid):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:8.1.2#2')
Ejemplo n.º 19
0
    def run_internal(self):
        """ Run the DES_02 test. """
        # Precondition.
        descriptors = get_descriptors_sequence.GetDescriptorsSequence(
            self.device_context).run()

        # Test step 1
        # Get MBIM communication interface.
        interfaces = usb_descriptors.filter_descriptors(
            usb_descriptors.InterfaceDescriptor, descriptors)

        mbim_communication_interfaces = (
            usb_descriptors.filter_interface_descriptors(
                interfaces, usb_descriptors.MBIM_ONLY_COMMUNICATION_INTERFACE))

        if not mbim_communication_interfaces:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#1')

        if len(mbim_communication_interfaces) > 1:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 mbim communication interface, got %d.' %
                (len(mbim_communication_interfaces)))
        mbim_communication_interface = mbim_communication_interfaces[0]

        # Test step 2
        # Get header functional descriptor, union functional descriptor,
        # MBIM functional descriptor and MBIM extended functional
        # descriptor.
        mbim_communication_interface_bundle = (
            usb_descriptors.get_descriptor_bundle(
                descriptors, mbim_communication_interface))

        header_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.HeaderFunctionalDescriptor,
            mbim_communication_interface_bundle)
        union_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.UnionFunctionalDescriptor,
            mbim_communication_interface_bundle)
        mbim_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.MBIMFunctionalDescriptor,
            mbim_communication_interface_bundle)
        mbim_extended_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.MBIMExtendedFunctionalDescriptor,
            mbim_communication_interface_bundle)
        if not (header_descriptors and union_descriptors and mbim_descriptors):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#2')

        # Test step 3
        # Check header functional descriptor.
        if usb_descriptors.has_distinct_descriptors(header_descriptors):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 unique header functional descriptor.')
        header_descriptor = header_descriptors[0]
        if not (header_descriptor.bDescriptorType == 0x24
                and header_descriptor.bDescriptorSubtype == 0x00
                and header_descriptor.bLength == 5
                and header_descriptor.bcdCDC >= 0x0120):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Header functional descriptor: wrong value(s)')

        # Test step 4
        # Check union functional descriptor.
        if usb_descriptors.has_distinct_descriptors(union_descriptors):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenerisAssertionError,
                'Expected 1 unique union functional descriptor.')
        union_descriptor = union_descriptors[0]
        if union_descriptor.index < header_descriptor.index:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#3')

        # Get CDC no data data interface.
        no_data_data_interfaces = usb_descriptors.filter_interface_descriptors(
            interfaces, usb_descriptors.MBIM_ONLY_DATA_INTERFACE_NO_DATA)
        if not no_data_data_interfaces:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.6#4')
        if len(no_data_data_interfaces) > 1:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Exactly 1 CDC data interface, got %d.' %
                (len(no_data_data_interfaces)))
        no_data_data_interface = no_data_data_interfaces[0]
        no_data_data_interface_bundle = usb_descriptors.get_descriptor_bundle(
            descriptors, no_data_data_interface)
        data_endpoint_descriptors = (usb_descriptors.filter_descriptors(
            usb_descriptors.EndpointDescriptor, no_data_data_interface_bundle))
        if data_endpoint_descriptors:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.6#2')

        # Get MBIM data interface.
        mbim_data_interfaces = usb_descriptors.filter_interface_descriptors(
            interfaces, usb_descriptors.MBIM_ONLY_DATA_INTERFACE_MBIM)
        if not mbim_data_interfaces:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.6#4')
        if len(mbim_data_interfaces) > 1:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 MBIM data interface, got %d.' %
                (len(mbim_data_interfaces)))
        mbim_data_interface = mbim_data_interfaces[0]

        # Check if there are two endpoint descriptors.
        if mbim_data_interface.bNumEndpoints != 2:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.6#3.')

        mbim_data_interface_bundle = usb_descriptors.get_descriptor_bundle(
            descriptors, mbim_data_interface)
        data_endpoint_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.EndpointDescriptor, mbim_data_interface_bundle)

        # Check the values of fields in endpoint descriptors.
        # There should be one bulk OUT and one bulk IN.
        if not usb_descriptors.has_bulk_in_and_bulk_out(
                data_endpoint_descriptors):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.6#3')

        # MBIM cdc data interface should have both no data data interface and
        # MBIM data interface. Therefore two interface numbers should be
        # the same.
        if (no_data_data_interface.bInterfaceNumber !=
                mbim_data_interface.bInterfaceNumber):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.6#1')

        # Check the fields of union functional descriptor
        if not (union_descriptor.bLength == 5 and
                (union_descriptor.bControlInterface
                 == mbim_communication_interface.bInterfaceNumber) and
                (union_descriptor.bSubordinateInterface0
                 == mbim_data_interface.bInterfaceNumber)):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#4')

        # Test step 5
        # Get MBIM functional descriptor.
        if usb_descriptors.has_distinct_descriptors(mbim_descriptors):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 unique MBIM functional descriptor.')
        mbim_descriptor = mbim_descriptors[0]

        if mbim_descriptor.index < header_descriptor.index:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#3')

        if mbim_descriptor.bLength != 12:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.4#5')

        if mbim_descriptor.bcdMBIMVersion != 0x0100:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.4#6')

        if mbim_descriptor.wMaxControlMessage < 64:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.4#1')

        if mbim_descriptor.bNumberFilters < 16:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.4#2')

        if mbim_descriptor.bMaxFilterSize > 192:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.4#3')

        # TODO(mcchou): Most of vendors set wMaxSegmentSize to be less than
        # 1500, so this assertion is skipped for now.
        #
        #if not mbim_descriptor.wMaxSegmentSize >= 2048:
        #    mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
        #                              'mbim1.0:6.4#4')

        # Use a byte as the mask to check if D0, D1, D2, D4, D6 and D7 are
        # zeros.
        if (mbim_descriptor.bmNetworkCapabilities & 0b11010111) > 0:
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.4#7')

        # Test step 6
        # Get MBIM extended functional descriptor, which is optional.
        if len(mbim_extended_descriptors) >= 1:
            if usb_descriptors.has_distinct_descriptors(
                    mbim_extended_descriptors):
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceGenerisAssertionError,
                    'Expected 1 unique MBIM extended functional '
                    'descriptor.')
            mbim_extended_descriptor = mbim_extended_descriptors[0]

            if mbim_extended_descriptor.index < mbim_descriptor.index:
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceAssertionError, 'mbim1.0:6.5#1')

            if mbim_extended_descriptor.bLength != 8:
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceAssertionError, 'mbim1.0:6.5#2')

            if mbim_extended_descriptor.bcdMBIMExtendedVersion != 0x0100:
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceAssertionError, 'mbim1.0:6.5#3')

            if mbim_extended_descriptor.bMaxOutstandingCommandMessages == 0:
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceAssertionError, 'mbim1.0:6.5#4')

        # Test step 7
        # Get the first endpoint for the communication interface.
        interrupt_endpoint_descriptors = usb_descriptors.filter_descriptors(
            usb_descriptors.EndpointDescriptor,
            mbim_communication_interface_bundle)

        if len(interrupt_endpoint_descriptors) != 1:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 endpoint, got %d.' %
                (len(interrupt_endpoint_descriptors)))
        interrupt_endpoint_descriptor = interrupt_endpoint_descriptors[0]
        if not (interrupt_endpoint_descriptor.bDescriptorType == 0x05
                and interrupt_endpoint_descriptor.bLength == 7
                and interrupt_endpoint_descriptor.bEndpointAddress >= 0x80
                and interrupt_endpoint_descriptor.bmAttributes == 0x03):
            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
                                      'mbim1.0:6.3#5')

        appear_before_functional_descriptors = False
        if mbim_extended_descriptors:
            if (mbim_extended_descriptor.index >
                    interrupt_endpoint_descriptor.index):
                appear_before_functional_descriptors = True
        else:
            if (mbim_descriptor.index > interrupt_endpoint_descriptor.index
                    or union_descriptor.index >
                    interrupt_endpoint_descriptor.index):
                appear_before_functional_descriptors = True
        if appear_before_functional_descriptors:
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'All functional descriptors must appear before endpoint'
                'descriptors.')

        # Test step 8
        # Get interface association descriptor.
        interface_association_descriptors = (
            usb_descriptors.filter_descriptors(
                usb_descriptors.InterfaceAssociationDescriptor, descriptors))

        if usb_descriptors.has_distinct_descriptors(
                interface_association_descriptors):
            mbim_errors.log_and_raise(
                mbim_errors.MBIMComplianceGenericAssertionError,
                'Expected 1 interface association descriptor, got %d.' %
                (len(interface_association_descriptors)))

        for association_descriptor in interface_association_descriptors:
            # Check interface association descriptor if one of the following
            # condition is met:
            # 1. bFirstInterface <= bControlInterface < (bFirstInterface +
            #                                            bInterfaceCount)
            # 2. bFirstInterface <= bSubordinateInterface0 < (
            #            bFirstInterface + bInterfaceCount)
            b_first_interface = association_descriptor.bFirstInterface
            b_interface_count = association_descriptor.bInterfaceCount
            b_control_interface = union_descriptor.bControlInterface
            b_subordinate_interface_0 = (
                union_descriptor.bSubordinateInterface0)
            check_inteface_association_descriptor = False

            if ((b_first_interface <= b_control_interface <
                 (b_first_interface + b_interface_count))
                    or (b_first_interface <= b_subordinate_interface_0 <
                        (b_first_interface + b_interface_count))):
                check_interface_association_descriptor = True

            if not check_interface_association_descriptor:
                mbim_errors.log_and_raise(
                    mbim_errors.MBIMComplianceAssertionError, 'mbim1.0:6.1#1')

            if check_interface_association_descriptor:
                if not (
                    (b_first_interface == b_control_interface
                     or b_first_interface == b_subordinate_interface_0) and
                    (b_interface_count == 2) and
                    (b_subordinate_interface_0 == b_control_interface + 1
                     or b_subordinate_interface_0 == b_control_interface - 1)
                        and (association_descriptor.bFunctionClass == 0x02) and
                    (association_descriptor.bFunctionSubClass == 0x0E) and
                    (association_descriptor.bFunctionProtocol == 0x00)):
                    mbim_errors.log_and_raise(
                        mbim_errors.MBIMComplianceAssertionError,
                        'mbim1.0:6.1#2')