blob: 707804ab404104a6cf1eb1538eac6ecb81ec1fa8 [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.
import logging
import common
from autotest_lib.client.bin import utils
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_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 \
import mbim_test_base
from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
import get_descriptors_sequence
from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
import mbim_open_generic_sequence
class cellular_MbimComplianceCM16(mbim_test_base.MbimTestBase):
"""
CM_16 Validation of fragmented message transmission in case of multiple
fragmented messages.
This test verifies that fragmented messages sent from the function are not
intermixed. Note that this test is only applicable for devices that support
multiple outstanding commands.
Reference:
[1] Universal Serial Bus Communication Class MBIM Compliance Testing: 44
http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
"""
version = 1
def run_internal(self):
""" Run CM_16 test. """
# Precondition
desc_sequence = get_descriptors_sequence.GetDescriptorsSequence(
self.device_context)
descriptors = desc_sequence.run()
self.device_context.update_descriptor_cache(descriptors)
open_sequence = mbim_open_generic_sequence.MBIMOpenGenericSequence(
self.device_context)
open_sequence.run(max_control_transfer_size=64)
device_context = self.device_context
descriptor_cache = device_context.descriptor_cache
self.channel = mbim_channel.MBIMChannel(
device_context.device,
descriptor_cache.mbim_communication_interface.bInterfaceNumber,
descriptor_cache.interrupt_endpoint.bEndpointAddress,
device_context.max_control_transfer_size)
# Step 1
caps_command_message = mbim_command_message.MBIMDeviceCapsQuery()
caps_packets = mbim_message_request.generate_request_packets(
caps_command_message,
device_context.max_control_transfer_size)
self.caps_transaction_id = caps_command_message.transaction_id
# Step 2
services_command_message = (
mbim_command_message.MBIMDeviceServicesQuery())
services_packets = mbim_message_request.generate_request_packets(
services_command_message,
device_context.max_control_transfer_size)
self.services_transaction_id = services_command_message.transaction_id
# Transmit the messages now
self.channel.unidirectional_transaction(*caps_packets)
self.channel.unidirectional_transaction(*services_packets)
# Step 3
utils.poll_for_condition(
self._get_response_packets,
timeout=5,
exception=mbim_errors.MBIMComplianceChannelError(
'Failed to retrieve the response packets to specific '
'control messages.'))
self.channel.close()
caps_response_message = self.caps_response
services_response_message = self.services_response
is_caps_message_valid = isinstance(
caps_response_message,
mbim_command_message.MBIMDeviceCapsInfo)
is_services_message_valid = isinstance(
services_response_message,
mbim_command_message.MBIMDeviceServicesInfo)
if not ((is_caps_message_valid and is_services_message_valid) and
(caps_response_message.transaction_id ==
caps_command_message.transaction_id) and
(caps_response_message.device_service_id ==
caps_command_message.device_service_id) and
caps_response_message.cid == caps_command_message.cid and
(services_command_message.transaction_id ==
services_response_message.transaction_id) and
(services_command_message.device_service_id ==
services_response_message.device_service_id) and
services_command_message.cid == services_response_message.cid):
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:9.5#1')
def _get_response_packets(self):
"""
Condition method for |poll_for_condition| to check the retrieval of
target packets.
@returns True if both caps response packet and services response packet
are received, False otherwise.
"""
try:
packets = self.channel.get_outstanding_packets()
except mbim_errors.MBIMComplianceChannelError:
logging.debug("Error in receiving response fragments from the device")
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:9.5#1')
self.caps_response = None
self.services_response = None
for packet in packets:
try:
message_response = mbim_message_response.parse_response_packets(
packet)
except mbim_errors.MBIMComplianceControlMessageError:
logging.debug("Error in parsing response fragments from the device")
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:9.5#1')
if message_response.transaction_id == self.caps_transaction_id:
self.caps_response = message_response
elif (message_response.transaction_id ==
self.services_transaction_id):
self.services_response = message_response
if self.caps_response and self.services_response:
return True
return False