# 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()