# 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.
"""
DES_01 Descriptors Validation for NCM/MBIM Functions
Reference:
[1] Universal Serial Bus Communication Class MBIM Compliance Testing: 23
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_errors
from autotest_lib.client.cros.cellular.mbim_compliance import test_context
from autotest_lib.client.cros.cellular.mbim_compliance import usb_descriptors
from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
import get_descriptors_sequence
from autotest_lib.client.cros.cellular.mbim_compliance.tests import des_test
class DES_01_Test(des_test.DesTest):
""" Implement the DES_01 Descriptors Validation for NCM/MBIM Functions """
def run_internal(self):
""" Run the DES_01 test. """
# Precondition.
descriptors = get_descriptors_sequence.GetDescriptorsSequence(
self.test_context).run()
device = self.test_context.device
if not device:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError,
'Device not found')
interfaces = usb_descriptors.filter_descriptors(
usb_descriptors.InterfaceDescriptor, descriptors)
# Test step 1
# Get ncm communication interface and mbim communication interface.
ncm_communication_interfaces = self.filter_interface_descriptors(
interfaces, self.NCM_MBIM_COMMUNICATION_INTERFACE_NCM)
if len(ncm_communication_interfaces) != 1:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.1#2')
ncm_communication_interface = ncm_communication_interfaces[0]
mbim_communication_interfaces = self.filter_interface_descriptors(
interfaces, self.NCM_MBIM_COMMUNICATION_INTERFACE_MBIM)
if len(mbim_communication_interfaces) != 1:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.1#3')
mbim_communication_interface = mbim_communication_interfaces[0]
if (ncm_communication_interface.bInterfaceNumber !=
mbim_communication_interface.bInterfaceNumber):
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.1#1')
# Test step 2
if (ncm_communication_interface.index >
mbim_communication_interface.index):
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceGenericAssertionError,
'Alternate setting 1 of the interface must appear after'
'alternate setting 0 of the interface.')
# Test step 3
# Get header functional descriptor, union functinoal descriptor,
# MBIM functinoal descriptor and MBIM extended functional
# descriptor from |ncm_communication_interface|[0].
ncm_communication_interface_bundle = (
usb_descriptors.get_descriptor_bundle(
descriptors, ncm_communication_interface))
header_descriptors = usb_descriptors.filter_descriptors(
usb_descriptors.HeaderFunctionalDescriptor,
ncm_communication_interface_bundle)
union_descriptors = usb_descriptors.filter_descriptors(
usb_descriptors.UnionFunctionalDescriptor,
ncm_communication_interface_bundle)
mbim_descriptors = usb_descriptors.filter_descriptors(
usb_descriptors.MBIMFunctionalDescriptor,
ncm_communication_interface_bundle)
mbim_extended_descriptors = usb_descriptors.filter_descriptors(
usb_descriptors.MBIMExtendedFunctionalDescriptor,
ncm_communication_interface_bundle)
if not(header_descriptors and union_descriptors and mbim_descriptors):
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:6.3#2')
# Test step 4
# Check header funcional descriptor.
if usb_descriptors.has_distinct_descriptors(header_descriptors):
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceGenericAssertionError,
'Expected 1 unique header functional descriptor.')
header_descriptor = header_descriptors[0]
if not(header_descriptor.bDescriptorType == 0x24 and
header_descriptor.bDescriptorSubtype == 0x00 and
header_descriptor.bLength == 5 and
header_descriptor.bcdCDC >= 0x0120):
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceGenericAssertionError,
'Header functional descriptor: wrong value(s)')
# Test step 5
# Check union functional descriptor.
if usb_descriptors.has_distinct_descriptors(union_descriptors):
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceGenericAssertionError,
'Expected 1 unique union functional descriptor.')
union_descriptor = union_descriptors[0]
if union_descriptor.index < header_descriptor.index:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:6.3#3')
# Get no data data interface.
no_data_data_interfaces = self.filter_interface_descriptors(
interfaces, self.NCM_MBIM_DATA_INTERFACE_NO_DATA)
if len(no_data_data_interfaces) != 1:
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#2')
no_data_data_interface = no_data_data_interfaces[0]
no_data_data_interface_bundle = usb_descriptors.get_descriptor_bundle(
descriptors, no_data_data_interface)
endpoint_descriptors = (
usb_descriptors.filter_descriptors(
usb_descriptors.EndpointDescriptor,
no_data_data_interface_bundle))
if endpoint_descriptors:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#4')
# Get NCM data interface.
ncm_data_interfaces = (
self.filter_interface_descriptors(
interfaces,
self.NCM_MBIM_DATA_INTERFACE_NCM))
if len(ncm_data_interfaces) != 1:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#2')
ncm_data_interface = ncm_data_interfaces[0]
if ncm_data_interface.bNumEndpoints != 2:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#4')
ncm_data_interface_bundle = (
usb_descriptors.get_descriptor_bundle(descriptors,
ncm_data_interface))
endpoint_descriptors = (
usb_descriptors.filter_descriptors(
usb_descriptors.EndpointDescriptor,
ncm_data_interface_bundle))
# Check endpoint descriptors in |ncm_data_interface_bundle|
# There should be one bulk OUT and one bulk IN.
if not self.has_bulk_in_and_bulk_out(endpoint_descriptors):
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#4')
# Get MBIM data interface.
mbim_data_interfaces = self.filter_interface_descriptors(
interfaces, self.NCM_MBIM_DATA_INTERFACE_MBIM)
if len(mbim_data_interfaces) != 1:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#3')
mbim_data_interface = mbim_data_interfaces[0]
if mbim_data_interface.bNumEndpoints != 2:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#4')
mbim_data_interface_bundle = (
usb_descriptors.get_descriptor_bundle(descriptors,
mbim_data_interface))
endpoint_descriptors = (
usb_descriptors.filter_descriptors(
usb_descriptors.EndpointDescriptor,
mbim_data_interface_bundle))
# Check endpoint descriptors in |mbim_data_interface_bundle|
# alternate setting 2. There should be one bulk OUT and one bulk IN.
if not self.has_bulk_in_and_bulk_out(endpoint_descriptors):
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#4')
if not(no_data_data_interface.bInterfaceNumber ==
ncm_data_interface.bInterfaceNumber ==
mbim_data_interface.bInterfaceNumber):
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:3.2.2.4#1')
if not(union_descriptor.bLength == 5 and
union_descriptor.bControlInterface == (
ncm_communication_interface.bInterfaceNumber) and
union_descriptors.bSubordinateInterface0 == (
no_data_data_interface.bInterfaceNumber)):
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
'mbim1.0:6.3#4')
# TODO(mcchou): Continue the remaining test steps.
# Update |test_context| with NCM/MBIM function settings.
if self.test_context.device_type == test_context.DEVICE_TYPE_MBIM:
mbim_errors.log_and_raise(mbim_errors.MBIMComplianceFrameworkError,
'A device can only be either a MBIM'
'device ro a NCM/MBIM device.')
self.test_context.device_type = test_context.DEVICE_TYPE_NCM_MBIM
self.test_context.ncm_communication_interface = (
ncm_communication_interface)
self.test_context.mbim_communication_interface = (
mbim_communication_interface)
self.test_context.no_data_data_interface = no_data_data_interface
self.test_context.ncm_data_interface = ncm_data_interface
self.test_context.mbim_data_interface = mbim_data_interface
# End of run_internal()