Home | History | Annotate | Download | only in sequences
      1 # Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import logging
      6 import struct
      7 from usb import control
      8 
      9 import common
     10 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
     11 from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
     12         import sequence
     13 
     14 # The maximun datagram size used in SetMaxDatagramSize request.
     15 MAX_DATAGRAM_SIZE = 1514
     16 
     17 
     18 #TODO(rpius): Move to a more appropriate location. Maybe a utility file?
     19 class NtbParameters(object):
     20     """ The class for NTB Parameter Structure. """
     21 
     22     _FIELDS = [('H','wLength'),
     23                ('H','bmNtbFormatsSupported'),
     24                ('I','dwNtbInMaxSize'),
     25                ('H','wNdpInDivisor'),
     26                ('H','wNdpInPayloadRemainder'),
     27                ('H','wNdpInAlignment'),
     28                ('H','reserved'),
     29                ('I','dwNtbOutMaxSize'),
     30                ('H','wNdpOutDivisor'),
     31                ('H','wNdpOutPayloadRemainder'),
     32                ('H','wNdpOutAlignment'),
     33                ('H','wNtbOutMaxDatagrams')]
     34 
     35 
     36     def __init__(self, *args):
     37         _, field_names = zip(*self._FIELDS)
     38         if len(args) != len(field_names):
     39             mbim_errors.log_and_raise(
     40                     mbim_errors.MBIMComplianceError,
     41                     'Expected %d arguments for %s constructor, got %d.' % (
     42                             len(field_names),self.__class__.__name__,len(args)))
     43 
     44         fields = zip(field_names, args)
     45         for field in fields:
     46             setattr(self, field[0], field[1])
     47 
     48 
     49     @classmethod
     50     def get_format_string(cls):
     51         """
     52         @returns The format string composed of concatenated field formats.
     53         """
     54         field_formats, _ = zip(*cls._FIELDS)
     55         return ''.join(field_format for field_format in field_formats)
     56 
     57 
     58 class OpenSequence(sequence.Sequence):
     59     """ Base case for all MBIM open sequneces. """
     60 
     61     def set_alternate_setting(self, interface_number, alternate_setting):
     62         """
     63         Set alternate setting to |alternate_setting| for the target interface.
     64 
     65         @param inteface_number: the index of target interface
     66         @param alternate_setting: expected value of alternate setting
     67 
     68         """
     69         logging.debug('SetInterface request: %d to interface-%d.',
     70                       alternate_setting, interface_number)
     71         control.set_interface(self.device_context.device,
     72                               interface_number,
     73                               alternate_setting)
     74 
     75 
     76     def reset_function(self, interface_number):
     77         """
     78         Send ResetFunction() request to the target interface.
     79 
     80         @param interface_number: the index of target interface
     81 
     82         """
     83         logging.debug('ResetFunction request to interface-%d.',
     84                       interface_number)
     85         self.device_context.device.ctrl_transfer(bmRequestType=0b00100001,
     86                                                  bRequest=0x05,
     87                                                  wValue=0,
     88                                                  wIndex=interface_number,
     89                                                  data_or_wLength=None)
     90 
     91 
     92     def get_ntb_parameters(self, interface_number):
     93         """
     94         Retrieve NTB parameters of the target interface.
     95 
     96         @param interface_number: the index of target interface
     97         @returns NTB parameters in byte stream.
     98 
     99         """
    100         logging.debug('GetNtbParameters request to interface-%d.',
    101                       interface_number)
    102         ntb_parameters = self.device_context.device.ctrl_transfer(
    103                 bmRequestType=0b10100001,
    104                 bRequest=0x80,
    105                 wValue=0,
    106                 wIndex=interface_number,
    107                 data_or_wLength=28)
    108         logging.debug('Response: %s', ntb_parameters)
    109         format_string = NtbParameters.get_format_string()
    110         return NtbParameters(
    111                 *struct.unpack_from('<' + format_string, ntb_parameters))
    112 
    113 
    114     def set_ntb_format(self, interface_number, ntb_format):
    115         """
    116         Send SetNtbFormat() request to the target interface.
    117 
    118         @param interface_number: the index of target interface
    119         @param ntb_format: The NTB format should be either |NTB_16| or |NTB_32|.
    120 
    121         """
    122         logging.debug('SetNtbFormat request: %d to interface-%d.',
    123                       ntb_format, interface_number)
    124         response = self.device_context.device.ctrl_transfer(
    125                 bmRequestType=0b00100001,
    126                 bRequest=0x84,
    127                 wValue=ntb_format,
    128                 wIndex=interface_number,
    129                 data_or_wLength=None)
    130         logging.debug('Response: %s', response)
    131 
    132 
    133     def get_ntb_format(self, interface_number):
    134         """
    135         Send GetNtbFormat() request to the target interface.
    136 
    137         @param interface_number: the index of target interface
    138         @returns ntb_format: The NTB format currently set.
    139 
    140         """
    141         logging.debug('GetNtbFormat request to interface-%d.',
    142                       interface_number)
    143         response = self.device_context.device.ctrl_transfer(
    144                 bmRequestType=0b10100001,
    145                 bRequest=0x83,
    146                 wValue=0,
    147                 wIndex=interface_number,
    148                 data_or_wLength=2)
    149         logging.debug('Response: %s', response)
    150         return response
    151 
    152 
    153     def set_ntb_input_size(self, interface_number, dw_ntb_in_max_size):
    154         """
    155         Send SetNtbInputSize() request to the target interface.
    156 
    157         @param interface_number:the index of target interface
    158         @param dw_ntb_in_max_size: The maxinum NTB size to set.
    159 
    160         """
    161         logging.debug('SetNtbInputSize request: %d to interface-%d.',
    162                       dw_ntb_in_max_size, interface_number)
    163         data = struct.pack('<I', dw_ntb_in_max_size)
    164         response = self.device_context.device.ctrl_transfer(
    165                 bmRequestType=0b00100001,
    166                 bRequest=0x86,
    167                 wIndex=interface_number,
    168                 data_or_wLength=data)
    169         logging.debug('Response: %s', response)
    170 
    171 
    172     def set_max_datagram_size(self, interface_number):
    173         """
    174         Send SetMaxDatagramSize() request to the target interface.
    175 
    176         @param interface_number: the index of target interface
    177 
    178         """
    179         logging.debug('SetMaxDatagramSize request: %d to interface-%d.',
    180                       MAX_DATAGRAM_SIZE, interface_number)
    181         data = struct.pack('<H', MAX_DATAGRAM_SIZE)
    182         response = self.device_context.device.ctrl_transfer(
    183                 bmRequestType=0b00100001,
    184                 bRequest=0x88,
    185                 wIndex=interface_number,
    186                 data_or_wLength=data)
    187         logging.debug('Response: %s', response)
    188