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