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""" 6DES_01 Descriptors Validation for NCM/MBIM Functions 7 8Reference: 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 14import common 15from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors 16from autotest_lib.client.cros.cellular.mbim_compliance import test_context 17from autotest_lib.client.cros.cellular.mbim_compliance import usb_descriptors 18from autotest_lib.client.cros.cellular.mbim_compliance.sequences \ 19 import get_descriptors_sequence 20from autotest_lib.client.cros.cellular.mbim_compliance.tests import des_test 21 22 23class 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