blob: 53cf0765c3de73ec404f6a08853b5ab5468cef5b [file] [log] [blame]
# 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.
"""
MBIM Open Generic Sequence
Reference:
[1] Universal Serial Bus Communication Class MBIM Compliance Testing: 19
http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
"""
import common
from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel
from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants
from autotest_lib.client.cros.cellular.mbim_compliance \
import mbim_device_context
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 open_sequence
class MBIMOpenGenericSequence(open_sequence.OpenSequence):
"""
Implement the MBIM Open Generic Sequence.
In this sequence, a |MBIM_OPEN_MSG| is sent from the host to the modem in
order to start the interaction. The modem should send a |MBIM_OPEN_DONE| as
the response to |MBIM_OPEN_MSG|.
"""
def run_internal(self,
max_control_transfer_size=None,
ntb_format=mbim_constants.NTB_FORMAT_32):
"""
Run the MBIM Open Generic Sequence.
@param max_control_transfer_size: Sets the max_control_transfer
parameter in the open message sent to the device and the size
of control buffers sent to the device.
@param ntb_format: Sets the NTB type to 16 bit vs 32 bit. This will only
be set on devices which support both 32 bit NTB and 16 bit NTB.
@returns tuple of (command_message, response_message):
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.
"""
# Step 1 and 2
device_context = self.device_context
device_type = device_context.device_type
mbim_communication_interface = (
device_context.descriptor_cache.mbim_communication_interface)
ncm_communication_interface = (
device_context.descriptor_cache.ncm_communication_interface)
no_data_data_interface = (
device_context.descriptor_cache.no_data_data_interface)
ncm_data_interface = (
device_context.descriptor_cache.ncm_data_interface)
mbim_data_interface = (
device_context.descriptor_cache.mbim_data_interface)
mbim_functional_descriptor = (
device_context.descriptor_cache.mbim_functional)
interrupt_endpoint = (
device_context.descriptor_cache.interrupt_endpoint)
descriptor_cache = device_context.descriptor_cache
communication_interface_number = (
mbim_communication_interface.bInterfaceNumber)
data_interface_number = mbim_data_interface.bInterfaceNumber
# Step 3
# Set alternate setting to be 0 for MBIM only data interface and
# NCM/MBIM data interface.
self.detach_kernel_driver_if_active(data_interface_number)
self.set_alternate_setting(data_interface_number, 0)
# Step 4
# Set alternate setting to be 1 for MBIM communication interface of
# NCM/MBIM function.
if device_type == mbim_device_context.DEVICE_TYPE_NCM_MBIM:
self.set_alternate_setting(communication_interface_number, 1)
# Step 5
# Send a RESET_FUNCTION(0x05) request to reset communication interface.
self.reset_function(communication_interface_number)
# Step 6
# Send GetNtbParameters() request to communication interface.
ntb_parameters = self.get_ntb_parameters(
mbim_communication_interface.bInterfaceNumber)
# Step 7
# Send SetNtbFormat() request to communication interface.
# Bit 1 of |bmNtbForatsSupported| indicates whether the device
# supports 32-bit NTBs.
if (ntb_parameters.bmNtbFormatsSupported >> 1) & 1:
self.set_ntb_format(communication_interface_number, ntb_format)
# Step 8
# Send SetNtbInputSize() request to communication interface.
self.set_ntb_input_size(communication_interface_number,
ntb_parameters.dwNtbInMaxSize)
# Step 9
# Send SetMaxDatagramSize() request to communication interface.
# Bit 3 determines whether the device can process SetMaxDatagramSize()
# and GetMaxDatagramSize() requests.
if (mbim_functional_descriptor.bmNetworkCapabilities>>3) & 1:
self.set_max_datagram_size(communication_interface_number)
# Step 10
if device_type == mbim_device_context.DEVICE_TYPE_MBIM:
alternate_setting = 1
else:
alternate_setting = 2
self.set_alternate_setting(data_interface_number, alternate_setting)
# Step 11 and 12
# Send MBIM_OPEN_MSG request and receive the response.
interrupt_endpoint_address = interrupt_endpoint.bEndpointAddress
# If |max_control_transfer_size| is not explicitly set by the test,
# we'll revert to using the |wMaxControlMessage| advertized by the
# device in the MBIM functional descriptor.
if not max_control_transfer_size:
max_control_transfer_size = (
mbim_functional_descriptor.wMaxControlMessage)
open_message = mbim_message_request.MBIMOpen(
max_control_transfer=max_control_transfer_size)
packets = mbim_message_request.generate_request_packets(
open_message,
max_control_transfer_size)
channel = mbim_channel.MBIMChannel(
device_context._device,
communication_interface_number,
interrupt_endpoint_address,
max_control_transfer_size)
response_packets = channel.bidirectional_transaction(*packets)
channel.close()
# Step 13
# Verify if MBIM_OPEN_MSG request succeeds.
response_message = mbim_message_response.parse_response_packets(
response_packets)
if response_message.transaction_id != open_message.transaction_id:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:9.4.1#1')
if response_message.status_codes != mbim_constants.MBIM_STATUS_SUCCESS:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceSequenceError,
'mbim1.0:9.4.1#2')
# Store data/control transfer parameters in the device context so that
# it can be used in any further control/data transfers.
device_context.max_control_transfer_size = max_control_transfer_size
device_context.current_ntb_format = self.get_ntb_format(
communication_interface_number)
device_context.max_in_data_transfer_size = (
ntb_parameters.dwNtbInMaxSize)
device_context.max_out_data_transfer_size = (
ntb_parameters.dwNtbOutMaxSize)
device_context.out_data_transfer_divisor = (
ntb_parameters.wNdpOutDivisor)
device_context.out_data_transfer_payload_remainder = (
ntb_parameters.wNdpOutPayloadRemainder)
device_context.out_data_transfer_ndp_alignment = (
ntb_parameters.wNdpOutAlignment)
return open_message, response_message