• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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