1# Lint as: python2, python3 2# Copyright (c) 2015 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7import unittest 8from array import array 9 10import common 11from autotest_lib.client.cros.cellular.mbim_compliance.usb_descriptors \ 12 import * 13 14 15class TestDescriptor(Descriptor): 16 """ Descriptor for unit testing. """ 17 DESCRIPTOR_TYPE = 0xAA 18 DESCRIPTOR_SUBTYPE = 0xBB 19 _FIELDS = (('B', 'bLength'), 20 ('B', 'bDescriptorType'), 21 ('B', 'bDescriptorSubtype')) 22 23 24class DescriptorTestCase(unittest.TestCase): 25 """ Test cases for verifying Descriptor classes and DescriptorParser. """ 26 27 28 def test_fields_not_defined(self): 29 """ 30 Verifies that an excepion is raised when constructing a Descriptor 31 subclass that does not define a _FIELDS attribute. 32 """ 33 with self.assertRaisesRegexp( 34 mbim_errors.MBIMComplianceFrameworkError, 35 'DescriptorFieldsNotDefined must define a _FIELDS attribute$'): 36 class DescriptorFieldsNotDefined(Descriptor): 37 """ Descriptor without _FIELDS attribute. """ 38 pass 39 40 41 def test_descriptor_type_not_defined(self): 42 """ 43 Verifies that it is OK to construct a Descriptor subclass that does not 44 define a DESCRIPTOR_TYPE attribute. 45 """ 46 class DescriptorTypeNotDefined(Descriptor): 47 """ Descriptor without DESCRIPTOR_TYPE attribute. """ 48 _FIELDS = (('B', 'bLength'), ('B', 'bDescriptorType')) 49 50 descriptor_data = array('B', [0x02, 0xAA]) 51 descriptor = DescriptorTypeNotDefined(descriptor_data) 52 self.assertEqual(2, descriptor.bLength) 53 self.assertEqual(0xAA, descriptor.bDescriptorType) 54 self.assertEqual(descriptor_data, descriptor.data) 55 56 57 def test_descriptor_type_mismatch(self): 58 """ 59 Verifies that an exception is raised when constructing a Descriptor 60 subclass from raw descriptor data with a descriptor type that differs 61 from the value specified by the DESCRIPTOR_TYPE attribute of the 62 subclass. 63 """ 64 with self.assertRaisesRegexp( 65 mbim_errors.MBIMComplianceFrameworkError, 66 '^Expected descriptor type 0xAA, got 0xBB$'): 67 descriptor = TestDescriptor(array('B', [0x03, 0xBB, 0xBB])) 68 69 70 def test_descriptor_subtype_mismatch(self): 71 """ 72 Verifies that an exception is raised when constructing a Descriptor 73 subclass from raw descriptor data with a descriptor subtype that differs 74 from the value specified by the DESCRIPTOR_SUBTYPE attribute of the 75 subclass. 76 """ 77 with self.assertRaisesRegexp( 78 mbim_errors.MBIMComplianceFrameworkError, 79 '^Expected descriptor subtype 0xBB, got 0xCC$'): 80 descriptor = TestDescriptor(array('B', [0x03, 0xAA, 0xCC])) 81 82 83 def test_descriptor_length_mismatch(self): 84 """ 85 Verifies that an exception is raised when constructing a Descriptor 86 subclass from raw descriptor data with a descriptor length that differs 87 from the length of the descriptor data. 88 """ 89 with self.assertRaisesRegexp( 90 mbim_errors.MBIMComplianceFrameworkError, 91 '^Expected descriptor length 3, got 1$'): 92 descriptor = TestDescriptor(array('B', [0x01, 0xAA, 0xBB])) 93 94 with self.assertRaisesRegexp( 95 mbim_errors.MBIMComplianceFrameworkError, 96 '^Expected descriptor length 3, got 4$'): 97 descriptor = TestDescriptor(array('B', [0x04, 0xAA, 0xBB])) 98 99 100 def test_descriptor_data_less_than_total_size_of_fields(self): 101 """ 102 Verifies that an exception is raised when constructing a Descriptor 103 subclass from raw descriptor data of length less than the total size of 104 fields specified by the _FIELDS attribute. 105 """ 106 with self.assertRaisesRegexp( 107 mbim_errors.MBIMComplianceFrameworkError, 108 '^Expected 3 or more bytes of descriptor data, got 1$'): 109 descriptor = TestDescriptor(array('B', [0x03])) 110 111 112 def test_descriptor_data_more_than_total_size_of_fields(self): 113 """ 114 Verifies that it is OK to construct a Descriptor subclass from raw 115 descriptor data of length more than the total size of fields specified 116 by the _FIELDS attribute. 117 """ 118 descriptor_data = array('B', [0x03, 0xAA, 0xBB]) 119 descriptor = TestDescriptor(descriptor_data) 120 self.assertEqual(3, descriptor.bLength) 121 self.assertEqual(0xAA, descriptor.bDescriptorType) 122 self.assertEqual(descriptor_data, descriptor.data) 123 124 125 def test_parsing_unknown_descriptor_type(self): 126 """ 127 Verifies that DescriptorParser returns an instance of UnknownDescriptor 128 when the descriptor type is not specified by any Descriptor subclass. 129 """ 130 descriptor_data = array('B', [0x02, 0xFF]) 131 descriptors = list(DescriptorParser(descriptor_data)) 132 self.assertEqual(1, len(descriptors)) 133 descriptor = descriptors[0] 134 self.assertIsInstance(descriptor, UnknownDescriptor) 135 self.assertEqual(2, descriptor.bLength) 136 self.assertEqual(0xFF, descriptor.bDescriptorType) 137 self.assertEqual(descriptor_data, descriptor.data) 138 139 140 def test_parsing_unsupported_descriptor_subtype(self): 141 """ 142 Verifies that DescriptorParser returns an instance of 143 FunctionalDescriptor when the descriptor type is 0x24 but the descriptor 144 subtype is not supported. 145 """ 146 descriptor_data = array('B', [0x03, 0x24, 0xFF]) 147 descriptors = list(DescriptorParser(descriptor_data)) 148 self.assertEqual(1, len(descriptors)) 149 descriptor = descriptors[0] 150 self.assertIsInstance(descriptor, FunctionalDescriptor) 151 self.assertEqual(3, descriptor.bLength) 152 self.assertEqual(0x24, descriptor.bDescriptorType) 153 self.assertEqual(0xFF, descriptor.bDescriptorSubtype) 154 self.assertEqual(descriptor_data, descriptor.data) 155 156 157 def test_parsing_descriptors(self): 158 """ 159 Verifies that DescriptorParser returns an instance of an appropriate 160 Descriptor subclass for each descriptor found in the given raw 161 descriptor data. 162 """ 163 descriptor_data = array('B', [0x09, 0x02, 0x5f, 0x00, 0x02, 0x01, 0x04, 164 0xa0, 0xfa, 0x08, 0x0b, 0x00, 0x02, 0x02, 165 0x0e, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 166 0x01, 0x02, 0x0e, 0x00, 0x05, 0x05, 0x24, 167 0x00, 0x20, 0x01, 0x0c, 0x24, 0x1b, 0x00, 168 0x01, 0x00, 0x06, 0x20, 0x80, 0x96, 0x05, 169 0x00, 0x08, 0x24, 0x1c, 0x00, 0x01, 0x0f, 170 0x96, 0x05, 0x05, 0x24, 0x06, 0x00, 0x01, 171 0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x05, 172 0x09, 0x04, 0x01, 0x00, 0x00, 0x0a, 0x00, 173 0x02, 0x06, 0x09, 0x04, 0x01, 0x01, 0x02, 174 0x0a, 0x00, 0x02, 0x07, 0x07, 0x05, 0x82, 175 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x01, 176 0x02, 0x00, 0x02, 0x00]) 177 parser = DescriptorParser(descriptor_data) 178 179 descriptor = next(parser) 180 self.assertIsInstance(descriptor, ConfigurationDescriptor) 181 self.assertIsInstance(descriptor, Descriptor) 182 self.assertEquals(9, descriptor.bLength) 183 self.assertEquals(0x02, descriptor.bDescriptorType) 184 self.assertEquals(95, descriptor.wTotalLength) 185 self.assertEquals(2, descriptor.bNumInterfaces) 186 self.assertEquals(1, descriptor.bConfigurationValue) 187 self.assertEquals(4, descriptor.iConfiguration) 188 self.assertEquals(0xA0, descriptor.bmAttributes) 189 self.assertEquals(250, descriptor.bMaxPower) 190 self.assertEqual(array('B', [0x09, 0x02, 0x5f, 0x00, 0x02, 0x01, 0x04, 191 0xa0, 0xfa]), 192 descriptor.data) 193 194 descriptor = next(parser) 195 self.assertIsInstance(descriptor, InterfaceAssociationDescriptor) 196 self.assertIsInstance(descriptor, Descriptor) 197 self.assertEquals(8, descriptor.bLength) 198 self.assertEquals(0x0B, descriptor.bDescriptorType) 199 self.assertEquals(0, descriptor.bFirstInterface) 200 self.assertEquals(2, descriptor.bInterfaceCount) 201 self.assertEquals(0x02, descriptor.bFunctionClass) 202 self.assertEquals(0x0E, descriptor.bFunctionSubClass) 203 self.assertEquals(0x00, descriptor.bFunctionProtocol) 204 self.assertEquals(0, descriptor.iFunction) 205 self.assertEqual(array('B', [0x08, 0x0b, 0x00, 0x02, 0x02, 0x0e, 0x00, 206 0x00]), 207 descriptor.data) 208 209 descriptor = next(parser) 210 self.assertIsInstance(descriptor, InterfaceDescriptor) 211 self.assertIsInstance(descriptor, Descriptor) 212 self.assertEquals(9, descriptor.bLength) 213 self.assertEquals(0x04, descriptor.bDescriptorType) 214 self.assertEquals(0, descriptor.bInterfaceNumber) 215 self.assertEquals(0, descriptor.bAlternateSetting) 216 self.assertEquals(1, descriptor.bNumEndpoints) 217 self.assertEquals(0x02, descriptor.bInterfaceClass) 218 self.assertEquals(0x0E, descriptor.bInterfaceSubClass) 219 self.assertEquals(0x00, descriptor.bInterfaceProtocol) 220 self.assertEquals(5, descriptor.iInterface) 221 self.assertEqual(array('B', [0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x0e, 222 0x00, 0x05]), 223 descriptor.data) 224 225 descriptor = next(parser) 226 self.assertIsInstance(descriptor, HeaderFunctionalDescriptor) 227 self.assertIsInstance(descriptor, FunctionalDescriptor) 228 self.assertIsInstance(descriptor, Descriptor) 229 self.assertEquals(5, descriptor.bLength) 230 self.assertEquals(0x24, descriptor.bDescriptorType) 231 self.assertEquals(0x00, descriptor.bDescriptorSubtype) 232 self.assertEquals(0x120, descriptor.bcdCDC) 233 self.assertEqual(array('B', [0x05, 0x24, 0x00, 0x20, 0x01]), 234 descriptor.data) 235 236 descriptor = next(parser) 237 self.assertIsInstance(descriptor, MBIMFunctionalDescriptor) 238 self.assertIsInstance(descriptor, FunctionalDescriptor) 239 self.assertIsInstance(descriptor, Descriptor) 240 self.assertEquals(12, descriptor.bLength) 241 self.assertEquals(0x24, descriptor.bDescriptorType) 242 self.assertEquals(0x1B, descriptor.bDescriptorSubtype) 243 self.assertEquals(0x100, descriptor.bcdMBIMVersion) 244 self.assertEquals(1536, descriptor.wMaxControlMessage) 245 self.assertEquals(32, descriptor.bNumberFilters) 246 self.assertEquals(128, descriptor.bMaxFilterSize) 247 self.assertEquals(1430, descriptor.wMaxSegmentSize) 248 self.assertEquals(0x00, descriptor.bmNetworkCapabilities) 249 self.assertEqual(array('B', [0x0c, 0x24, 0x1b, 0x00, 0x01, 0x00, 0x06, 250 0x20, 0x80, 0x96, 0x05, 0x00]), 251 descriptor.data) 252 253 descriptor = next(parser) 254 self.assertIsInstance(descriptor, MBIMExtendedFunctionalDescriptor) 255 self.assertIsInstance(descriptor, FunctionalDescriptor) 256 self.assertIsInstance(descriptor, Descriptor) 257 self.assertEquals(8, descriptor.bLength) 258 self.assertEquals(0x24, descriptor.bDescriptorType) 259 self.assertEquals(0x1C, descriptor.bDescriptorSubtype) 260 self.assertEquals(0x100, descriptor.bcdMBIMExtendedVersion) 261 self.assertEquals(15, descriptor.bMaxOutstandingCommandMessages) 262 self.assertEquals(1430, descriptor.wMTU) 263 self.assertEqual(array('B', [0x08, 0x24, 0x1c, 0x00, 0x01, 0x0f, 0x96, 264 0x05]), 265 descriptor.data) 266 267 descriptor = next(parser) 268 self.assertIsInstance(descriptor, UnionFunctionalDescriptor) 269 self.assertIsInstance(descriptor, FunctionalDescriptor) 270 self.assertIsInstance(descriptor, Descriptor) 271 self.assertEquals(5, descriptor.bLength) 272 self.assertEquals(0x24, descriptor.bDescriptorType) 273 self.assertEquals(0x06, descriptor.bDescriptorSubtype) 274 self.assertEquals(0, descriptor.bControlInterface) 275 self.assertEquals(1, descriptor.bSubordinateInterface0) 276 self.assertEqual(array('B', [0x05, 0x24, 0x06, 0x00, 0x01]), 277 descriptor.data) 278 279 descriptor = next(parser) 280 self.assertIsInstance(descriptor, EndpointDescriptor) 281 self.assertIsInstance(descriptor, Descriptor) 282 self.assertEquals(7, descriptor.bLength) 283 self.assertEquals(0x05, descriptor.bDescriptorType) 284 self.assertEquals(0x81, descriptor.bEndpointAddress) 285 self.assertEquals(0x03, descriptor.bmAttributes) 286 self.assertEquals(64, descriptor.wMaxPacketSize) 287 self.assertEquals(5, descriptor.bInterval) 288 self.assertEqual(array('B', [0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x05]), 289 descriptor.data) 290 291 descriptor = next(parser) 292 self.assertIsInstance(descriptor, InterfaceDescriptor) 293 self.assertIsInstance(descriptor, Descriptor) 294 self.assertEquals(9, descriptor.bLength) 295 self.assertEquals(0x04, descriptor.bDescriptorType) 296 self.assertEquals(1, descriptor.bInterfaceNumber) 297 self.assertEquals(0, descriptor.bAlternateSetting) 298 self.assertEquals(0, descriptor.bNumEndpoints) 299 self.assertEquals(0x0A, descriptor.bInterfaceClass) 300 self.assertEquals(0x00, descriptor.bInterfaceSubClass) 301 self.assertEquals(0x02, descriptor.bInterfaceProtocol) 302 self.assertEquals(6, descriptor.iInterface) 303 self.assertEqual(array('B', [0x09, 0x04, 0x01, 0x00, 0x00, 0x0a, 0x00, 304 0x02, 0x06]), 305 descriptor.data) 306 307 descriptor = next(parser) 308 self.assertIsInstance(descriptor, InterfaceDescriptor) 309 self.assertIsInstance(descriptor, Descriptor) 310 self.assertEquals(9, descriptor.bLength) 311 self.assertEquals(0x04, descriptor.bDescriptorType) 312 self.assertEquals(1, descriptor.bInterfaceNumber) 313 self.assertEquals(1, descriptor.bAlternateSetting) 314 self.assertEquals(2, descriptor.bNumEndpoints) 315 self.assertEquals(0x0A, descriptor.bInterfaceClass) 316 self.assertEquals(0x00, descriptor.bInterfaceSubClass) 317 self.assertEquals(0x02, descriptor.bInterfaceProtocol) 318 self.assertEquals(7, descriptor.iInterface) 319 self.assertEqual(array('B', [0x09, 0x04, 0x01, 0x01, 0x02, 0x0a, 0x00, 320 0x02, 0x07]), 321 descriptor.data) 322 323 descriptor = next(parser) 324 self.assertIsInstance(descriptor, EndpointDescriptor) 325 self.assertIsInstance(descriptor, Descriptor) 326 self.assertEquals(7, descriptor.bLength) 327 self.assertEquals(0x05, descriptor.bDescriptorType) 328 self.assertEquals(0x82, descriptor.bEndpointAddress) 329 self.assertEquals(0x02, descriptor.bmAttributes) 330 self.assertEquals(512, descriptor.wMaxPacketSize) 331 self.assertEquals(0, descriptor.bInterval) 332 self.assertEqual(array('B', [0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00]), 333 descriptor.data) 334 335 descriptor = next(parser) 336 self.assertIsInstance(descriptor, EndpointDescriptor) 337 self.assertIsInstance(descriptor, Descriptor) 338 self.assertEquals(7, descriptor.bLength) 339 self.assertEquals(0x05, descriptor.bDescriptorType) 340 self.assertEquals(0x01, descriptor.bEndpointAddress) 341 self.assertEquals(0x02, descriptor.bmAttributes) 342 self.assertEquals(512, descriptor.wMaxPacketSize) 343 self.assertEquals(0, descriptor.bInterval) 344 self.assertEqual(array('B', [0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00]), 345 descriptor.data) 346 347 with self.assertRaises(StopIteration): 348 descriptor = next(parser) 349 350 351if __name__ == '__main__': 352 logging.basicConfig(level=logging.DEBUG) 353 unittest.main() 354