# Copyright 2015 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """ Connect Sequence Reference: [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 20 http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf """ import array import common from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel from autotest_lib.client.cros.cellular.mbim_compliance \ import mbim_command_message from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors from autotest_lib.client.cros.cellular.mbim_compliance \ import mbim_message_request from autotest_lib.client.cros.cellular.mbim_compliance \ import mbim_message_response from autotest_lib.client.cros.cellular.mbim_compliance.sequences \ import sequence class ConnectSequence(sequence.Sequence): """ Implement the Connect Sequence. """ def run_internal(self, introduce_error_in_access_offset=False, introduce_error_in_packets_order=None, raise_exception_on_failure=True): """ Run the Connect Sequence. Once the command message is sent, there should be at least one notification received apart from the command done message. @param introduce_error_in_access_offset: Whether to introduce an error in the access_string offset or not. @param introduce_error_in_packets_order: Whether to introduce an error in the order of packets sent or not. It's a user provided list of packet sequence numbers to reorder, repeat or remove packets generated for connect before sending it to the device. @param raise_exception_on_failure: Whether to raise an exception or not. @returns tuple of (command_message, response_message, notifications): command_message: The command message sent to device. |command_message| is a MBIMCommandMessage object. response_message: The response to the |command_message|. |response_message| is a MBIMCommandDoneMessage object. notifications: The list of notifications message sent from the modem to the host. |notifications| is a list of |MBIMIndicateStatusMessage| objects. """ # Step 1 # Send MBIM_COMMAND_MSG. context_type = mbim_constants.MBIM_CONTEXT_TYPE_INTERNET.bytes data_buffer = array.array('B', 'loopback'.encode('utf-16le')) information_buffer_length = ( mbim_command_message.MBIMSetConnect.get_struct_len()) information_buffer_length += len(data_buffer) device_context = self.device_context descriptor_cache = device_context.descriptor_cache if introduce_error_in_access_offset: access_string_offset = 0 else: access_string_offset = 60 command_message = ( mbim_command_message.MBIMSetConnect(session_id=0, activation_command=1, access_string_offset=access_string_offset, access_string_size=16, user_name_offset=0, user_name_size=0, password_offset=0, password_size=0, compression=0, auth_protocol=0, ip_type=1, context_type=context_type, information_buffer_length=information_buffer_length, payload_buffer=data_buffer)) packets = mbim_message_request.generate_request_packets( command_message, device_context.max_control_transfer_size) channel = mbim_channel.MBIMChannel( device_context._device, descriptor_cache.mbim_communication_interface.bInterfaceNumber, descriptor_cache.interrupt_endpoint.bEndpointAddress, device_context.max_control_transfer_size) if introduce_error_in_packets_order is not None: packets = [packets[i] for i in introduce_error_in_packets_order] response_packets = channel.bidirectional_transaction(*packets) notifications_packets = channel.get_outstanding_packets(); channel.close() # Step 2 response_message = mbim_message_response.parse_response_packets( response_packets) notifications = [] for notification_packets in notifications_packets: notifications.append( mbim_message_response.parse_response_packets( notification_packets)) # Step 3 if (response_message.message_type != mbim_constants.MBIM_COMMAND_DONE or response_message.status_codes != mbim_constants.MBIM_STATUS_SUCCESS): if raise_exception_on_failure: mbim_errors.log_and_raise( mbim_errors.MBIMComplianceSequenceError, 'Connect sequence failed.') return command_message, response_message, notifications