• 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 struct
7from usb import control
8
9import common
10from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
11from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
12        import sequence
13
14# The maximun datagram size used in SetMaxDatagramSize request.
15MAX_DATAGRAM_SIZE = 1514
16
17
18#TODO(rpius): Move to a more appropriate location. Maybe a utility file?
19class NtbParameters(object):
20    """ The class for NTB Parameter Structure. """
21
22    _FIELDS = [('H','wLength'),
23               ('H','bmNtbFormatsSupported'),
24               ('I','dwNtbInMaxSize'),
25               ('H','wNdpInDivisor'),
26               ('H','wNdpInPayloadRemainder'),
27               ('H','wNdpInAlignment'),
28               ('H','reserved'),
29               ('I','dwNtbOutMaxSize'),
30               ('H','wNdpOutDivisor'),
31               ('H','wNdpOutPayloadRemainder'),
32               ('H','wNdpOutAlignment'),
33               ('H','wNtbOutMaxDatagrams')]
34
35
36    def __init__(self, *args):
37        _, field_names = zip(*self._FIELDS)
38        if len(args) != len(field_names):
39            mbim_errors.log_and_raise(
40                    mbim_errors.MBIMComplianceError,
41                    'Expected %d arguments for %s constructor, got %d.' % (
42                            len(field_names),self.__class__.__name__,len(args)))
43
44        fields = zip(field_names, args)
45        for field in fields:
46            setattr(self, field[0], field[1])
47
48
49    @classmethod
50    def get_format_string(cls):
51        """
52        @returns The format string composed of concatenated field formats.
53        """
54        field_formats, _ = zip(*cls._FIELDS)
55        return ''.join(field_format for field_format in field_formats)
56
57
58class OpenSequence(sequence.Sequence):
59    """ Base case for all MBIM open sequneces. """
60
61    def set_alternate_setting(self, interface_number, alternate_setting):
62        """
63        Set alternate setting to |alternate_setting| for the target interface.
64
65        @param inteface_number: the index of target interface
66        @param alternate_setting: expected value of alternate setting
67
68        """
69        logging.debug('SetInterface request: %d to interface-%d.',
70                      alternate_setting, interface_number)
71        control.set_interface(self.device_context.device,
72                              interface_number,
73                              alternate_setting)
74
75
76    def reset_function(self, interface_number):
77        """
78        Send ResetFunction() request to the target interface.
79
80        @param interface_number: the index of target interface
81
82        """
83        logging.debug('ResetFunction request to interface-%d.',
84                      interface_number)
85        self.device_context.device.ctrl_transfer(bmRequestType=0b00100001,
86                                                 bRequest=0x05,
87                                                 wValue=0,
88                                                 wIndex=interface_number,
89                                                 data_or_wLength=None)
90
91
92    def get_ntb_parameters(self, interface_number):
93        """
94        Retrieve NTB parameters of the target interface.
95
96        @param interface_number: the index of target interface
97        @returns NTB parameters in byte stream.
98
99        """
100        logging.debug('GetNtbParameters request to interface-%d.',
101                      interface_number)
102        ntb_parameters = self.device_context.device.ctrl_transfer(
103                bmRequestType=0b10100001,
104                bRequest=0x80,
105                wValue=0,
106                wIndex=interface_number,
107                data_or_wLength=28)
108        logging.debug('Response: %s', ntb_parameters)
109        format_string = NtbParameters.get_format_string()
110        return NtbParameters(
111                *struct.unpack_from('<' + format_string, ntb_parameters))
112
113
114    def set_ntb_format(self, interface_number, ntb_format):
115        """
116        Send SetNtbFormat() request to the target interface.
117
118        @param interface_number: the index of target interface
119        @param ntb_format: The NTB format should be either |NTB_16| or |NTB_32|.
120
121        """
122        logging.debug('SetNtbFormat request: %d to interface-%d.',
123                      ntb_format, interface_number)
124        response = self.device_context.device.ctrl_transfer(
125                bmRequestType=0b00100001,
126                bRequest=0x84,
127                wValue=ntb_format,
128                wIndex=interface_number,
129                data_or_wLength=None)
130        logging.debug('Response: %s', response)
131
132
133    def get_ntb_format(self, interface_number):
134        """
135        Send GetNtbFormat() request to the target interface.
136
137        @param interface_number: the index of target interface
138        @returns ntb_format: The NTB format currently set.
139
140        """
141        logging.debug('GetNtbFormat request to interface-%d.',
142                      interface_number)
143        response = self.device_context.device.ctrl_transfer(
144                bmRequestType=0b10100001,
145                bRequest=0x83,
146                wValue=0,
147                wIndex=interface_number,
148                data_or_wLength=2)
149        logging.debug('Response: %s', response)
150        return response
151
152
153    def set_ntb_input_size(self, interface_number, dw_ntb_in_max_size):
154        """
155        Send SetNtbInputSize() request to the target interface.
156
157        @param interface_number:the index of target interface
158        @param dw_ntb_in_max_size: The maxinum NTB size to set.
159
160        """
161        logging.debug('SetNtbInputSize request: %d to interface-%d.',
162                      dw_ntb_in_max_size, interface_number)
163        data = struct.pack('<I', dw_ntb_in_max_size)
164        response = self.device_context.device.ctrl_transfer(
165                bmRequestType=0b00100001,
166                bRequest=0x86,
167                wIndex=interface_number,
168                data_or_wLength=data)
169        logging.debug('Response: %s', response)
170
171
172    def set_max_datagram_size(self, interface_number):
173        """
174        Send SetMaxDatagramSize() request to the target interface.
175
176        @param interface_number: the index of target interface
177
178        """
179        logging.debug('SetMaxDatagramSize request: %d to interface-%d.',
180                      MAX_DATAGRAM_SIZE, interface_number)
181        data = struct.pack('<H', MAX_DATAGRAM_SIZE)
182        response = self.device_context.device.ctrl_transfer(
183                bmRequestType=0b00100001,
184                bRequest=0x88,
185                wIndex=interface_number,
186                data_or_wLength=data)
187        logging.debug('Response: %s', response)
188