Home | History | Annotate | Download | only in tests
      1 # Copyright (c) 2014 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 """
      6 CM_05 Validatation for modem's responses to two consecutive MBIM command
      7 messages are correct with regards to |transaction_id|, |service_id| and |cid|.
      8 
      9 Reference:
     10     [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 39
     11         http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf
     12 """
     13 import common
     14 from autotest_lib.client.bin import utils
     15 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel
     16 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants
     17 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_control
     18 from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
     19 from autotest_lib.client.cros.cellular.mbim_compliance.sequences \
     20         import mbim_open_generic_sequence
     21 from autotest_lib.client.cros.cellular.mbim_compliance.tests import test
     22 
     23 
     24 class CM05Test(test.Test):
     25     """ Implement the CM_05 test. """
     26 
     27     def run_internal(self):
     28         """ Run CM_05 test. """
     29         # Precondition
     30         mbim_open_generic_sequence.MBIMOpenGenericSequence(
     31                 self.test_context).run()
     32 
     33         caps_command_message = mbim_control.MBIMCommandMessage(
     34                 device_service_id=mbim_constants.UUID_BASIC_CONNECT.bytes,
     35                 cid=mbim_constants.MBIM_CID_DEVICE_CAPS,
     36                 command_type=mbim_constants.COMMAND_TYPE_QUERY,
     37                 information_buffer_length=0)
     38         caps_packets = caps_command_message.generate_packets()
     39         services_command_message = mbim_control.MBIMCommandMessage(
     40                 device_service_id=mbim_constants.UUID_BASIC_CONNECT.bytes,
     41                 cid=mbim_constants.MBIM_CID_DEVICE_SERVICES,
     42                 command_type=mbim_constants.COMMAND_TYPE_QUERY,
     43                 information_buffer_length=0)
     44         services_packets = services_command_message.generate_packets()
     45         self.caps_transaction_id = caps_command_message.transaction_id
     46         self.services_transaction_id = services_command_message.transaction_id
     47         self.channel = mbim_channel.MBIMChannel(
     48                 {'idVendor': self.test_context.id_vendor,
     49                  'idProduct': self.test_context.id_product},
     50                 self.test_context.mbim_communication_interface.bInterfaceNumber,
     51                 self.test_context.interrupt_endpoint.bEndpointAddress,
     52                 self.test_context.mbim_functional.wMaxControlMessage)
     53         # Step 1
     54         self.channel.unidirectional_transaction(*caps_packets)
     55         # Step 2
     56         self.channel.unidirectional_transaction(*services_packets)
     57 
     58         utils.poll_for_condition(
     59                 self._get_response_packets,
     60                 timeout=5,
     61                 exception=mbim_errors.MBIMComplianceChannelError(
     62                         'Failed to retrieve the response packets to specific '
     63                         'control messages.'))
     64 
     65         self.channel.close()
     66         caps_response_message = mbim_control.parse_response_packets(
     67                 self.caps_response_packet)
     68         services_response_message = mbim_control.parse_response_packets(
     69                 self.services_response_packet)
     70 
     71         # Step 3
     72         if not ((caps_response_message.transaction_id ==
     73                  caps_command_message.transaction_id) and
     74                 (caps_response_message.device_service_id ==
     75                  caps_command_message.device_service_id) and
     76                 caps_response_message.cid == caps_command_message.cid and
     77                 (services_command_message.transaction_id ==
     78                  services_response_message.transaction_id) and
     79                 (services_command_message.device_service_id ==
     80                  services_response_message.device_service_id) and
     81                 services_command_message.cid == services_response_message.cid):
     82             mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError,
     83                                       'mbim1.0:8.1.2#2')
     84 
     85 
     86     def _get_response_packets(self):
     87         """
     88         Condition method for |poll_for_condition| to check the retrieval of
     89         target packets.
     90 
     91         @returns True if both caps response packet and services response packet
     92                 are received, False otherwise.
     93 
     94         """
     95         self.caps_response_packet, self.services_response_packet = None, None
     96         packets = self.channel.get_outstanding_packets()
     97         header = {}
     98         for packet in packets:
     99             for fragment in packet:
    100                 try:
    101                     header = mbim_control.MBIMHeader.unpack(fragment)
    102                 except mbim_errors.MBIMComplianceControlMessageError:
    103                     continue
    104                 if header.get('transaction_id') == self.caps_transaction_id:
    105                     self.caps_response_packet = packet
    106                 elif (header.get('transaction_id') ==
    107                       self.services_transaction_id):
    108                     self.services_response_packet = packet
    109                 if self.caps_response_packet and self.services_response_packet:
    110                     return True
    111         return False
    112