blob: eae9a5cf8a8bfc1794e62b847add1ddb85671740 [file] [log] [blame]
# Copyright (c) 2014 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
"""
from usb import core
import common
from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel
from autotest_lib.client.cros.cellular.mbim_compliance import mbim_control
from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
from autotest_lib.client.cros.cellular.mbim_compliance import test_context
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):
""" Run the MBIM Open Generic Sequence. """
# Step 1 and 2
# Find communication interface and data interface for MBIM only function
mbim_found, ncm_mbim_found = False, False
if self.test_context.device_type == test_context.DEVICE_TYPE_MBIM:
mbim_communication_interface = (
self.test_context.mbim_communication_interface)
no_data_data_interface = self.test_context.no_data_data_interface
mbim_data_interface = self.test_context.mbim_data_interface
mbim_found = True
elif self.test_context.device_type == test_context.DEVICE_TYPE_NCM_MBIM:
mbim_communication_interface = (
self.test_context.mbim_communication_interface)
ncm_communication_interface = (
self.test_context.ncm_communication_interface)
no_data_data_interface = self.test_context.no_data_data_interface
ncm_data_interface = self.test_context.ncm_data_interface
mbim_data_interface = self.test_context.mbim_data_interface
ncm_mbim_found = True
else:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError,
'No MBIM or NCM/MBIM function found.')
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 ncm_mbim_found:
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 uses
# 16-bit or 32-bit NTBs
if (ntb_parameters.bmNtbFormatsSupported>>1) & 1:
self.set_ntb_format(communication_interface_number,
open_sequence.NTB_32)
# 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.
mbim_functional_descriptor = self.test_context.mbim_functional
# 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 mbim_found:
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 = (
self.test_context.interrupt_endpoint.bEndpointAddress)
# TODO(mcchou): For unblocking the CM_xx tests. A new version of
# message contructing will be presented.
max_control_message = (
mbim_functional_descriptor.wMaxControlMessage)
open_message = mbim_control.MBIMOpenMessage(
max_control_transfer=max_control_message)
packets = open_message.generate_packets()
device_filter = {'idVendor': self.test_context.id_vendor,
'idProduct': self.test_context.id_product}
# TODO(mcchou): Come up with a way to release the device.
#device_copy = self.test_context.device
del self.test_context._device
channel = mbim_channel.MBIMChannel(
device_filter,
communication_interface_number,
interrupt_endpoint_address,
mbim_functional_descriptor.wMaxControlMessage)
response_packets = channel.bidirectional_transaction(*packets)
channel.close()
# TODO(mcchou): Remove the code after we hava a better solution.
self.test_context._device = core.find(
idVendor=self.test_context.id_vendor,
idProduct=self.test_context.id_product)
# Step 13
# Verify if MBIM_OPEN_MSG request succeeds.
response_message = mbim_control.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_control.MBIM_STATUS_SUCCESS:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceSequenceError,
'mbim1.0:9.4.1#2')
return open_message, response_message