Home | History | Annotate | Download | only in tests
      1 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """
      6 DES_01 Descriptors Validation for NCM/MBIM Functions
      7 
      8 Reference:
      9     [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 23
     10         http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
     11 
     12 """
     13 
     14 import common
     15 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
     16 from autotest_lib.client.cros.cellular.mbim_compliance import test_context
     17 from autotest_lib.client.cros.cellular.mbim_compliance import usb_descriptors
     18 from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
     19         import get_descriptors_sequence
     20 from autotest_lib.client.cros.cellular.mbim_compliance.tests import des_test
     21 
     22 
     23 class DES_01_Test(des_test.DesTest):
     24     """ Implement the DES_01 Descriptors Validation for NCM/MBIM Functions """
     25 
     26     def run_internal(self):
     27         """ Run the DES_01 test. """
     28         # Precondition.
     29         descriptors = get_descriptors_sequence.GetDescriptorsSequence(
     30                 self.test_context).run()
     31         device = self.test_context.device
     32         if not device:
     33             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError,
     34                                       'Device not found')
     35         interfaces = usb_descriptors.filter_descriptors(
     36                 usb_descriptors.InterfaceDescriptor, descriptors)
     37 
     38         # Test step 1
     39         # Get ncm communication interface and mbim communication interface.
     40         ncm_communication_interfaces = self.filter_interface_descriptors(
     41                 interfaces, self.NCM_MBIM_COMMUNICATION_INTERFACE_NCM)
     42 
     43         if len(ncm_communication_interfaces) != 1:
     44             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
     45                                       'mbim1.0:3.2.1#2')
     46 
     47         ncm_communication_interface = ncm_communication_interfaces[0]
     48 
     49         mbim_communication_interfaces = self.filter_interface_descriptors(
     50                 interfaces, self.NCM_MBIM_COMMUNICATION_INTERFACE_MBIM)
     51 
     52         if len(mbim_communication_interfaces) != 1:
     53             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
     54                                       'mbim1.0:3.2.1#3')
     55 
     56         mbim_communication_interface = mbim_communication_interfaces[0]
     57 
     58         if (ncm_communication_interface.bInterfaceNumber !=
     59             mbim_communication_interface.bInterfaceNumber):
     60             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
     61                                       'mbim1.0:3.2.1#1')
     62 
     63         # Test step 2
     64         if (ncm_communication_interface.index >
     65             mbim_communication_interface.index):
     66             mbim_errors.log_and_raise(
     67                     mbim_errors.MBIMComplianceGenericAssertionError,
     68                     'Alternate setting 1 of the interface must appear after'
     69                     'alternate setting 0 of the interface.')
     70 
     71         # Test step 3
     72         # Get header functional descriptor, union functinoal descriptor,
     73         # MBIM functinoal descriptor and MBIM extended functional
     74         # descriptor from |ncm_communication_interface|[0].
     75         ncm_communication_interface_bundle = (
     76                 usb_descriptors.get_descriptor_bundle(
     77                         descriptors, ncm_communication_interface))
     78 
     79         header_descriptors = usb_descriptors.filter_descriptors(
     80                 usb_descriptors.HeaderFunctionalDescriptor,
     81                 ncm_communication_interface_bundle)
     82         union_descriptors = usb_descriptors.filter_descriptors(
     83                 usb_descriptors.UnionFunctionalDescriptor,
     84                 ncm_communication_interface_bundle)
     85         mbim_descriptors = usb_descriptors.filter_descriptors(
     86                 usb_descriptors.MBIMFunctionalDescriptor,
     87                 ncm_communication_interface_bundle)
     88         mbim_extended_descriptors = usb_descriptors.filter_descriptors(
     89                 usb_descriptors.MBIMExtendedFunctionalDescriptor,
     90                 ncm_communication_interface_bundle)
     91         if not(header_descriptors and union_descriptors and mbim_descriptors):
     92             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
     93                                       'mbim1.0:6.3#2')
     94 
     95         # Test step 4
     96         # Check header funcional descriptor.
     97         if usb_descriptors.has_distinct_descriptors(header_descriptors):
     98             mbim_errors.log_and_raise(
     99                     mbim_errors.MBIMComplianceGenericAssertionError,
    100                     'Expected 1 unique header functional descriptor.')
    101         header_descriptor = header_descriptors[0]
    102         if not(header_descriptor.bDescriptorType == 0x24 and
    103                header_descriptor.bDescriptorSubtype == 0x00 and
    104                header_descriptor.bLength == 5 and
    105                header_descriptor.bcdCDC >= 0x0120):
    106             mbim_errors.log_and_raise(
    107                     mbim_errors.MBIMComplianceGenericAssertionError,
    108                     'Header functional descriptor: wrong value(s)')
    109 
    110         # Test step 5
    111         # Check union functional descriptor.
    112         if usb_descriptors.has_distinct_descriptors(union_descriptors):
    113             mbim_errors.log_and_raise(
    114                     mbim_errors.MBIMComplianceGenericAssertionError,
    115                     'Expected 1 unique union functional descriptor.')
    116 
    117         union_descriptor = union_descriptors[0]
    118         if union_descriptor.index < header_descriptor.index:
    119             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    120                                       'mbim1.0:6.3#3')
    121         # Get no data data interface.
    122         no_data_data_interfaces = self.filter_interface_descriptors(
    123                 interfaces, self.NCM_MBIM_DATA_INTERFACE_NO_DATA)
    124 
    125         if len(no_data_data_interfaces) != 1:
    126             mbim_errors.log_and_raise(
    127                     mbim_errors.MBIMComplianceAssertionError,
    128                     'mbim1.0:3.2.2.4#2')
    129 
    130         no_data_data_interface = no_data_data_interfaces[0]
    131         no_data_data_interface_bundle = usb_descriptors.get_descriptor_bundle(
    132                 descriptors, no_data_data_interface)
    133         endpoint_descriptors = (
    134                 usb_descriptors.filter_descriptors(
    135                         usb_descriptors.EndpointDescriptor,
    136                         no_data_data_interface_bundle))
    137 
    138         if endpoint_descriptors:
    139             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    140                                       'mbim1.0:3.2.2.4#4')
    141 
    142         # Get NCM data interface.
    143         ncm_data_interfaces = (
    144                 self.filter_interface_descriptors(
    145                         interfaces,
    146                         self.NCM_MBIM_DATA_INTERFACE_NCM))
    147 
    148         if len(ncm_data_interfaces) != 1:
    149             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    150                                       'mbim1.0:3.2.2.4#2')
    151         ncm_data_interface = ncm_data_interfaces[0]
    152         if ncm_data_interface.bNumEndpoints != 2:
    153             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    154                                       'mbim1.0:3.2.2.4#4')
    155         ncm_data_interface_bundle = (
    156                 usb_descriptors.get_descriptor_bundle(descriptors,
    157                                                       ncm_data_interface))
    158         endpoint_descriptors = (
    159                 usb_descriptors.filter_descriptors(
    160                         usb_descriptors.EndpointDescriptor,
    161                         ncm_data_interface_bundle))
    162         # Check endpoint descriptors in |ncm_data_interface_bundle|
    163         # There should be one bulk OUT and one bulk IN.
    164         if not self.has_bulk_in_and_bulk_out(endpoint_descriptors):
    165             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    166                                       'mbim1.0:3.2.2.4#4')
    167 
    168         # Get MBIM data interface.
    169         mbim_data_interfaces = self.filter_interface_descriptors(
    170                 interfaces, self.NCM_MBIM_DATA_INTERFACE_MBIM)
    171 
    172         if len(mbim_data_interfaces) != 1:
    173            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    174                                      'mbim1.0:3.2.2.4#3')
    175         mbim_data_interface = mbim_data_interfaces[0]
    176         if mbim_data_interface.bNumEndpoints != 2:
    177             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    178                                       'mbim1.0:3.2.2.4#4')
    179 
    180         mbim_data_interface_bundle = (
    181                 usb_descriptors.get_descriptor_bundle(descriptors,
    182                                                       mbim_data_interface))
    183         endpoint_descriptors = (
    184                 usb_descriptors.filter_descriptors(
    185                         usb_descriptors.EndpointDescriptor,
    186                         mbim_data_interface_bundle))
    187         # Check endpoint descriptors in |mbim_data_interface_bundle|
    188         # alternate setting 2. There should be one bulk OUT and one bulk IN.
    189         if not self.has_bulk_in_and_bulk_out(endpoint_descriptors):
    190             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    191                                       'mbim1.0:3.2.2.4#4')
    192 
    193         if not(no_data_data_interface.bInterfaceNumber ==
    194                ncm_data_interface.bInterfaceNumber ==
    195                mbim_data_interface.bInterfaceNumber):
    196             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    197                                       'mbim1.0:3.2.2.4#1')
    198 
    199         if not(union_descriptor.bLength == 5 and
    200                union_descriptor.bControlInterface == (
    201                        ncm_communication_interface.bInterfaceNumber) and
    202                union_descriptors.bSubordinateInterface0 == (
    203                        no_data_data_interface.bInterfaceNumber)):
    204             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
    205                                       'mbim1.0:6.3#4')
    206         # TODO(mcchou): Continue the remaining test steps.
    207 
    208         # Update |test_context| with NCM/MBIM function settings.
    209         if self.test_context.device_type == test_context.DEVICE_TYPE_MBIM:
    210             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError,
    211                                       'A device can only be either a MBIM'
    212                                       'device ro a NCM/MBIM device.')
    213         self.test_context.device_type = test_context.DEVICE_TYPE_NCM_MBIM
    214         self.test_context.ncm_communication_interface = (
    215                 ncm_communication_interface)
    216         self.test_context.mbim_communication_interface = (
    217                 mbim_communication_interface)
    218         self.test_context.no_data_data_interface = no_data_data_interface
    219         self.test_context.ncm_data_interface = ncm_data_interface
    220         self.test_context.mbim_data_interface = mbim_data_interface
    221     # End of run_internal()
    222