Home | History | Annotate | Download | only in sequences
      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 """
      6 MBIM Open Generic Sequence
      7 
      8 Reference:
      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 
     13 import common
     14 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel
     15 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants
     16 from autotest_lib.client.cros.cellular.mbim_compliance \
     17         import mbim_device_context
     18 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
     19 from autotest_lib.client.cros.cellular.mbim_compliance \
     20         import mbim_message_request
     21 from autotest_lib.client.cros.cellular.mbim_compliance \
     22         import mbim_message_response
     23 from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
     24         import open_sequence
     25 
     26 
     27 class 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