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