| # Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """ |
| DES_01 Descriptors Validation for NCM/MBIM Functions |
| |
| Reference: |
| [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 23 |
| http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf |
| |
| """ |
| |
| import common |
| from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors |
| from autotest_lib.client.cros.cellular.mbim_compliance import test_context |
| from autotest_lib.client.cros.cellular.mbim_compliance import usb_descriptors |
| from autotest_lib.client.cros.cellular.mbim_compliance.sequences \ |
| import get_descriptors_sequence |
| from autotest_lib.client.cros.cellular.mbim_compliance.tests import des_test |
| |
| |
| class DES_01_Test(des_test.DesTest): |
| """ Implement the DES_01 Descriptors Validation for NCM/MBIM Functions """ |
| |
| def run_internal(self): |
| """ Run the DES_01 test. """ |
| # Precondition. |
| descriptors = get_descriptors_sequence.GetDescriptorsSequence( |
| self.test_context).run() |
| device = self.test_context.device |
| if not device: |
| mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError, |
| 'Device not found') |
| interfaces = usb_descriptors.filter_descriptors( |
| usb_descriptors.InterfaceDescriptor, descriptors) |
| |
| # Test step 1 |
| # Get ncm communication interface and mbim communication interface. |
| ncm_communication_interfaces = self.filter_interface_descriptors( |
| interfaces, self.NCM_MBIM_COMMUNICATION_INTERFACE_NCM) |
| |
| 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] |
| |
| mbim_communication_interfaces = self.filter_interface_descriptors( |
| interfaces, self.NCM_MBIM_COMMUNICATION_INTERFACE_MBIM) |
| |
| 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 = self.filter_interface_descriptors( |
| interfaces, self.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 = ( |
| self.filter_interface_descriptors( |
| interfaces, |
| self.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 self.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 = self.filter_interface_descriptors( |
| interfaces, self.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 self.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') |
| # TODO(mcchou): Continue the remaining test steps. |
| |
| # Update |test_context| with NCM/MBIM function settings. |
| if self.test_context.device_type == test_context.DEVICE_TYPE_MBIM: |
| mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError, |
| 'A device can only be either a MBIM' |
| 'device ro a NCM/MBIM device.') |
| self.test_context.device_type = test_context.DEVICE_TYPE_NCM_MBIM |
| self.test_context.ncm_communication_interface = ( |
| ncm_communication_interface) |
| self.test_context.mbim_communication_interface = ( |
| mbim_communication_interface) |
| self.test_context.no_data_data_interface = no_data_data_interface |
| self.test_context.ncm_data_interface = ncm_data_interface |
| self.test_context.mbim_data_interface = mbim_data_interface |
| # End of run_internal() |