# Copyright (c) 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 struct from usb import control import common from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors from autotest_lib.client.cros.cellular.mbim_compliance.sequences \ import sequence # The maximun datagram size used in SetMaxDatagramSize request. MAX_DATAGRAM_SIZE = 1514 #TODO(rpius): Move to a more appropriate location. Maybe a utility file? class NtbParameters(object): """ The class for NTB Parameter Structure. """ _FIELDS = [('H','wLength'), ('H','bmNtbFormatsSupported'), ('I','dwNtbInMaxSize'), ('H','wNdpInDivisor'), ('H','wNdpInPayloadRemainder'), ('H','wNdpInAlignment'), ('H','reserved'), ('I','dwNtbOutMaxSize'), ('H','wNdpOutDivisor'), ('H','wNdpOutPayloadRemainder'), ('H','wNdpOutAlignment'), ('H','wNtbOutMaxDatagrams')] def __init__(self, *args): _, field_names = zip(*self._FIELDS) if len(args) != len(field_names): mbim_errors.log_and_raise( mbim_errors.MBIMComplianceError, 'Expected %d arguments for %s constructor, got %d.' % ( len(field_names),self.__class__.__name__,len(args))) fields = zip(field_names, args) for field in fields: setattr(self, field[0], field[1]) @classmethod def get_format_string(cls): """ @returns The format string composed of concatenated field formats. """ field_formats, _ = zip(*cls._FIELDS) return ''.join(field_format for field_format in field_formats) class OpenSequence(sequence.Sequence): """ Base case for all MBIM open sequneces. """ def set_alternate_setting(self, interface_number, alternate_setting): """ Set alternate setting to |alternate_setting| for the target interface. @param inteface_number: the index of target interface @param alternate_setting: expected value of alternate setting """ logging.debug('SetInterface request: %d to interface-%d.', alternate_setting, interface_number) control.set_interface(self.device_context.device, interface_number, alternate_setting) def reset_function(self, interface_number): """ Send ResetFunction() request to the target interface. @param interface_number: the index of target interface """ logging.debug('ResetFunction request to interface-%d.', interface_number) self.device_context.device.ctrl_transfer(bmRequestType=0b00100001, bRequest=0x05, wValue=0, wIndex=interface_number, data_or_wLength=None) def get_ntb_parameters(self, interface_number): """ Retrieve NTB parameters of the target interface. @param interface_number: the index of target interface @returns NTB parameters in byte stream. """ logging.debug('GetNtbParameters request to interface-%d.', interface_number) ntb_parameters = self.device_context.device.ctrl_transfer( bmRequestType=0b10100001, bRequest=0x80, wValue=0, wIndex=interface_number, data_or_wLength=28) logging.debug('Response: %s', ntb_parameters) format_string = NtbParameters.get_format_string() return NtbParameters( *struct.unpack_from('<' + format_string, ntb_parameters)) def set_ntb_format(self, interface_number, ntb_format): """ Send SetNtbFormat() request to the target interface. @param interface_number: the index of target interface @param ntb_format: The NTB format should be either |NTB_16| or |NTB_32|. """ logging.debug('SetNtbFormat request: %d to interface-%d.', ntb_format, interface_number) response = self.device_context.device.ctrl_transfer( bmRequestType=0b00100001, bRequest=0x84, wValue=ntb_format, wIndex=interface_number, data_or_wLength=None) logging.debug('Response: %s', response) def get_ntb_format(self, interface_number): """ Send GetNtbFormat() request to the target interface. @param interface_number: the index of target interface @returns ntb_format: The NTB format currently set. """ logging.debug('GetNtbFormat request to interface-%d.', interface_number) response = self.device_context.device.ctrl_transfer( bmRequestType=0b10100001, bRequest=0x83, wValue=0, wIndex=interface_number, data_or_wLength=2) logging.debug('Response: %s', response) return response def set_ntb_input_size(self, interface_number, dw_ntb_in_max_size): """ Send SetNtbInputSize() request to the target interface. @param interface_number:the index of target interface @param dw_ntb_in_max_size: The maxinum NTB size to set. """ logging.debug('SetNtbInputSize request: %d to interface-%d.', dw_ntb_in_max_size, interface_number) data = struct.pack('<I', dw_ntb_in_max_size) response = self.device_context.device.ctrl_transfer( bmRequestType=0b00100001, bRequest=0x86, wIndex=interface_number, data_or_wLength=data) logging.debug('Response: %s', response) def set_max_datagram_size(self, interface_number): """ Send SetMaxDatagramSize() request to the target interface. @param interface_number: the index of target interface """ logging.debug('SetMaxDatagramSize request: %d to interface-%d.', MAX_DATAGRAM_SIZE, interface_number) data = struct.pack('<H', MAX_DATAGRAM_SIZE) response = self.device_context.device.ctrl_transfer( bmRequestType=0b00100001, bRequest=0x88, wIndex=interface_number, data_or_wLength=data) logging.debug('Response: %s', response)