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 Connect Sequence
      6 
      7 Reference:
      8     [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 20
      9         http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
     10 """
     11 import array
     12 import common
     13 
     14 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel
     15 from autotest_lib.client.cros.cellular.mbim_compliance \
     16         import mbim_command_message
     17 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants
     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 sequence
     25 
     26 
     27 class ConnectSequence(sequence.Sequence):
     28     """ Implement the Connect Sequence. """
     29 
     30     def run_internal(self,
     31                      introduce_error_in_access_offset=False,
     32                      introduce_error_in_packets_order=None,
     33                      raise_exception_on_failure=True):
     34         """
     35         Run the Connect Sequence.
     36 
     37         Once the command message is sent, there should be at least one
     38         notification received apart from the command done message.
     39 
     40         @param introduce_error_in_access_offset: Whether to introduce an
     41                 error in the access_string offset or not.
     42         @param introduce_error_in_packets_order: Whether to introduce an
     43                 error in the order of packets sent or not. It's a user provided
     44                 list of packet sequence numbers to reorder, repeat or remove
     45                 packets generated for connect before sending it to the device.
     46         @param raise_exception_on_failure: Whether to raise an exception or not.
     47         @returns tuple of (command_message, response_message, notifications):
     48                 command_message: The command message sent to device.
     49                 |command_message| is a MBIMCommandMessage object.
     50                 response_message: The response to the |command_message|.
     51                 |response_message| is a MBIMCommandDoneMessage object.
     52                 notifications: The list of notifications message sent from the
     53                 modem to the host. |notifications| is a list of
     54                 |MBIMIndicateStatusMessage| objects.
     55         """
     56         # Step 1
     57         # Send MBIM_COMMAND_MSG.
     58         context_type = mbim_constants.MBIM_CONTEXT_TYPE_INTERNET.bytes
     59         data_buffer = array.array('B', 'loopback'.encode('utf-16le'))
     60         information_buffer_length = (
     61                 mbim_command_message.MBIMSetConnect.get_struct_len())
     62         information_buffer_length += len(data_buffer)
     63         device_context = self.device_context
     64         descriptor_cache = device_context.descriptor_cache
     65         if introduce_error_in_access_offset:
     66             access_string_offset = 0
     67         else:
     68             access_string_offset = 60
     69         command_message = (
     70                 mbim_command_message.MBIMSetConnect(session_id=0,
     71                         activation_command=1,
     72                         access_string_offset=access_string_offset,
     73                         access_string_size=16,
     74                         user_name_offset=0,
     75                         user_name_size=0,
     76                         password_offset=0,
     77                         password_size=0,
     78                         compression=0,
     79                         auth_protocol=0,
     80                         ip_type=1,
     81                         context_type=context_type,
     82                         information_buffer_length=information_buffer_length,
     83                         payload_buffer=data_buffer))
     84         packets = mbim_message_request.generate_request_packets(
     85                 command_message,
     86                 device_context.max_control_transfer_size)
     87         channel = mbim_channel.MBIMChannel(
     88                 device_context._device,
     89                 descriptor_cache.mbim_communication_interface.bInterfaceNumber,
     90                 descriptor_cache.interrupt_endpoint.bEndpointAddress,
     91                 device_context.max_control_transfer_size)
     92         if introduce_error_in_packets_order is not None:
     93             packets = [packets[i] for i in introduce_error_in_packets_order]
     94         response_packets = channel.bidirectional_transaction(*packets)
     95         notifications_packets = channel.get_outstanding_packets();
     96         channel.close()
     97 
     98         # Step 2
     99         response_message = mbim_message_response.parse_response_packets(
    100                 response_packets)
    101         notifications = []
    102         for notification_packets in notifications_packets:
    103             notifications.append(
    104                     mbim_message_response.parse_response_packets(
    105                             notification_packets))
    106 
    107         # Step 3
    108         if (response_message.message_type != mbim_constants.MBIM_COMMAND_DONE or
    109             response_message.status_codes != mbim_constants.MBIM_STATUS_SUCCESS):
    110             if raise_exception_on_failure:
    111                 mbim_errors.log_and_raise(
    112                         mbim_errors.MBIMComplianceSequenceError,
    113                         'Connect sequence failed.')
    114 
    115         return command_message, response_message, notifications
    116