# 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