• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 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
5"""
6MBIM Open Generic Sequence
7
8Reference:
9    [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 19
10        http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
11"""
12
13import common
14from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel
15from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants
16from autotest_lib.client.cros.cellular.mbim_compliance \
17        import mbim_device_context
18from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
19from autotest_lib.client.cros.cellular.mbim_compliance \
20        import mbim_message_request
21from autotest_lib.client.cros.cellular.mbim_compliance \
22        import mbim_message_response
23from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
24        import open_sequence
25
26
27class MBIMOpenGenericSequence(open_sequence.OpenSequence):
28    """
29    Implement the MBIM Open Generic Sequence.
30    In this sequence, a |MBIM_OPEN_MSG| is sent from the host to the modem in
31    order to start the interaction. The modem should send a |MBIM_OPEN_DONE| as
32    the response to |MBIM_OPEN_MSG|.
33    """
34
35    def run_internal(self,
36                     max_control_transfer_size=None,
37                     ntb_format=mbim_constants.NTB_FORMAT_32):
38        """
39        Run the MBIM Open Generic Sequence.
40
41        @param max_control_transfer_size: Sets the max_control_transfer
42                parameter in the open message sent to the device and the size
43                of control buffers sent to the device.
44        @param ntb_format: Sets the NTB type to 16 bit vs 32 bit. This will only
45                be set on devices which support both 32 bit NTB and 16 bit NTB.
46        @returns tuple of (command_message, response_message):
47                command_message: The command message sent to device.
48                |command_message| is a MBIMCommandMessage object.
49                response_message: The response to the |command_message|.
50                |response_message| is a MBIMCommandDoneMessage object.
51        """
52        # Step 1 and 2
53        device_context = self.device_context
54        device_type = device_context.device_type
55        mbim_communication_interface = (
56                device_context.descriptor_cache.mbim_communication_interface)
57        ncm_communication_interface = (
58                device_context.descriptor_cache.ncm_communication_interface)
59        no_data_data_interface = (
60                device_context.descriptor_cache.no_data_data_interface)
61        ncm_data_interface = (
62                device_context.descriptor_cache.ncm_data_interface)
63        mbim_data_interface = (
64                device_context.descriptor_cache.mbim_data_interface)
65        mbim_functional_descriptor = (
66                device_context.descriptor_cache.mbim_functional)
67        interrupt_endpoint = (
68                device_context.descriptor_cache.interrupt_endpoint)
69        descriptor_cache = device_context.descriptor_cache
70
71        communication_interface_number = (
72                mbim_communication_interface.bInterfaceNumber)
73        data_interface_number = mbim_data_interface.bInterfaceNumber
74
75        # Step 3
76        # Set alternate setting to be 0 for MBIM only data interface and
77        # NCM/MBIM data interface.
78        self.detach_kernel_driver_if_active(data_interface_number)
79        self.set_alternate_setting(data_interface_number, 0)
80
81        # Step 4
82        # Set alternate setting to be 1 for MBIM communication interface of
83        # NCM/MBIM function.
84        if device_type == mbim_device_context.DEVICE_TYPE_NCM_MBIM:
85            self.set_alternate_setting(communication_interface_number, 1)
86
87        # Step 5
88        # Send a RESET_FUNCTION(0x05) request to reset communication interface.
89        self.reset_function(communication_interface_number)
90
91        # Step 6
92        # Send GetNtbParameters() request to communication interface.
93        ntb_parameters = self.get_ntb_parameters(
94                mbim_communication_interface.bInterfaceNumber)
95
96        # Step 7
97        # Send SetNtbFormat() request to communication interface.
98        # Bit 1 of |bmNtbForatsSupported| indicates whether the device
99        # supports 32-bit NTBs.
100        if (ntb_parameters.bmNtbFormatsSupported >> 1) & 1:
101            self.set_ntb_format(communication_interface_number, ntb_format)
102
103        # Step 8
104        # Send SetNtbInputSize() request to communication interface.
105        self.set_ntb_input_size(communication_interface_number,
106                                ntb_parameters.dwNtbInMaxSize)
107
108        # Step 9
109        # Send SetMaxDatagramSize() request to communication interface.
110        # Bit 3 determines whether the device can process SetMaxDatagramSize()
111        # and GetMaxDatagramSize() requests.
112        if (mbim_functional_descriptor.bmNetworkCapabilities>>3) & 1:
113            self.set_max_datagram_size(communication_interface_number)
114
115        # Step 10
116        if device_type == mbim_device_context.DEVICE_TYPE_MBIM:
117            alternate_setting = 1
118        else:
119            alternate_setting = 2
120        self.set_alternate_setting(data_interface_number, alternate_setting)
121
122        # Step 11 and 12
123        # Send MBIM_OPEN_MSG request and receive the response.
124        interrupt_endpoint_address = interrupt_endpoint.bEndpointAddress
125
126        # If |max_control_transfer_size| is not explicitly set by the test,
127        # we'll revert to using the |wMaxControlMessage| advertized by the
128        # device in the MBIM functional descriptor.
129        if not max_control_transfer_size:
130            max_control_transfer_size = (
131                    mbim_functional_descriptor.wMaxControlMessage)
132        open_message = mbim_message_request.MBIMOpen(
133                max_control_transfer=max_control_transfer_size)
134        packets = mbim_message_request.generate_request_packets(
135                open_message,
136                max_control_transfer_size)
137        channel = mbim_channel.MBIMChannel(
138                device_context._device,
139                communication_interface_number,
140                interrupt_endpoint_address,
141                max_control_transfer_size)
142        response_packets = channel.bidirectional_transaction(*packets)
143        channel.close()
144
145        # Step 13
146        # Verify if MBIM_OPEN_MSG request succeeds.
147        response_message = mbim_message_response.parse_response_packets(
148                response_packets)
149
150        if response_message.transaction_id != open_message.transaction_id:
151            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
152                                      'mbim1.0:9.4.1#1')
153
154        if response_message.status_codes != mbim_constants.MBIM_STATUS_SUCCESS:
155            mbim_errors.log_and_raise(mbim_errors.MBIMComplianceSequenceError,
156                                      'mbim1.0:9.4.1#2')
157
158        # Store data/control transfer parameters in the device context so that
159        # it can be used in any further control/data transfers.
160        device_context.max_control_transfer_size = max_control_transfer_size
161        device_context.current_ntb_format = self.get_ntb_format(
162                communication_interface_number)
163        device_context.max_in_data_transfer_size = (
164                ntb_parameters.dwNtbInMaxSize)
165        device_context.max_out_data_transfer_size = (
166                ntb_parameters.dwNtbOutMaxSize)
167        device_context.out_data_transfer_divisor = (
168                ntb_parameters.wNdpOutDivisor)
169        device_context.out_data_transfer_payload_remainder = (
170                ntb_parameters.wNdpOutPayloadRemainder)
171        device_context.out_data_transfer_ndp_alignment = (
172                ntb_parameters.wNdpOutAlignment)
173
174        return open_message, response_message
175