1# Copyright 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""" 6MBIM Open Generic Sequence 7 8Reference: 9 [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 19 10 http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf 11""" 12 13import common 14from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel 15from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants 16from autotest_lib.client.cros.cellular.mbim_compliance \ 17 import mbim_device_context 18from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors 19from autotest_lib.client.cros.cellular.mbim_compliance \ 20 import mbim_message_request 21from autotest_lib.client.cros.cellular.mbim_compliance \ 22 import mbim_message_response 23from autotest_lib.client.cros.cellular.mbim_compliance.sequences \ 24 import open_sequence 25 26 27class MBIMOpenGenericSequence(open_sequence.OpenSequence): 28 """ 29 Implement the MBIM Open Generic Sequence. 30 In this sequence, a |MBIM_OPEN_MSG| is sent from the host to the modem in 31 order to start the interaction. The modem should send a |MBIM_OPEN_DONE| as 32 the response to |MBIM_OPEN_MSG|. 33 """ 34 35 def run_internal(self, 36 max_control_transfer_size=None, 37 ntb_format=mbim_constants.NTB_FORMAT_32): 38 """ 39 Run the MBIM Open Generic Sequence. 40 41 @param max_control_transfer_size: Sets the max_control_transfer 42 parameter in the open message sent to the device and the size 43 of control buffers sent to the device. 44 @param ntb_format: Sets the NTB type to 16 bit vs 32 bit. This will only 45 be set on devices which support both 32 bit NTB and 16 bit NTB. 46 @returns tuple of (command_message, response_message): 47 command_message: The command message sent to device. 48 |command_message| is a MBIMCommandMessage object. 49 response_message: The response to the |command_message|. 50 |response_message| is a MBIMCommandDoneMessage object. 51 """ 52 # Step 1 and 2 53 device_context = self.device_context 54 device_type = device_context.device_type 55 mbim_communication_interface = ( 56 device_context.descriptor_cache.mbim_communication_interface) 57 ncm_communication_interface = ( 58 device_context.descriptor_cache.ncm_communication_interface) 59 no_data_data_interface = ( 60 device_context.descriptor_cache.no_data_data_interface) 61 ncm_data_interface = ( 62 device_context.descriptor_cache.ncm_data_interface) 63 mbim_data_interface = ( 64 device_context.descriptor_cache.mbim_data_interface) 65 mbim_functional_descriptor = ( 66 device_context.descriptor_cache.mbim_functional) 67 interrupt_endpoint = ( 68 device_context.descriptor_cache.interrupt_endpoint) 69 descriptor_cache = device_context.descriptor_cache 70 71 communication_interface_number = ( 72 mbim_communication_interface.bInterfaceNumber) 73 data_interface_number = mbim_data_interface.bInterfaceNumber 74 75 # Step 3 76 # Set alternate setting to be 0 for MBIM only data interface and 77 # NCM/MBIM data interface. 78 self.detach_kernel_driver_if_active(data_interface_number) 79 self.set_alternate_setting(data_interface_number, 0) 80 81 # Step 4 82 # Set alternate setting to be 1 for MBIM communication interface of 83 # NCM/MBIM function. 84 if device_type == mbim_device_context.DEVICE_TYPE_NCM_MBIM: 85 self.set_alternate_setting(communication_interface_number, 1) 86 87 # Step 5 88 # Send a RESET_FUNCTION(0x05) request to reset communication interface. 89 self.reset_function(communication_interface_number) 90 91 # Step 6 92 # Send GetNtbParameters() request to communication interface. 93 ntb_parameters = self.get_ntb_parameters( 94 mbim_communication_interface.bInterfaceNumber) 95 96 # Step 7 97 # Send SetNtbFormat() request to communication interface. 98 # Bit 1 of |bmNtbForatsSupported| indicates whether the device 99 # supports 32-bit NTBs. 100 if (ntb_parameters.bmNtbFormatsSupported >> 1) & 1: 101 self.set_ntb_format(communication_interface_number, ntb_format) 102 103 # Step 8 104 # Send SetNtbInputSize() request to communication interface. 105 self.set_ntb_input_size(communication_interface_number, 106 ntb_parameters.dwNtbInMaxSize) 107 108 # Step 9 109 # Send SetMaxDatagramSize() request to communication interface. 110 # Bit 3 determines whether the device can process SetMaxDatagramSize() 111 # and GetMaxDatagramSize() requests. 112 if (mbim_functional_descriptor.bmNetworkCapabilities>>3) & 1: 113 self.set_max_datagram_size(communication_interface_number) 114 115 # Step 10 116 if device_type == mbim_device_context.DEVICE_TYPE_MBIM: 117 alternate_setting = 1 118 else: 119 alternate_setting = 2 120 self.set_alternate_setting(data_interface_number, alternate_setting) 121 122 # Step 11 and 12 123 # Send MBIM_OPEN_MSG request and receive the response. 124 interrupt_endpoint_address = interrupt_endpoint.bEndpointAddress 125 126 # If |max_control_transfer_size| is not explicitly set by the test, 127 # we'll revert to using the |wMaxControlMessage| advertized by the 128 # device in the MBIM functional descriptor. 129 if not max_control_transfer_size: 130 max_control_transfer_size = ( 131 mbim_functional_descriptor.wMaxControlMessage) 132 open_message = mbim_message_request.MBIMOpen( 133 max_control_transfer=max_control_transfer_size) 134 packets = mbim_message_request.generate_request_packets( 135 open_message, 136 max_control_transfer_size) 137 channel = mbim_channel.MBIMChannel( 138 device_context._device, 139 communication_interface_number, 140 interrupt_endpoint_address, 141 max_control_transfer_size) 142 response_packets = channel.bidirectional_transaction(*packets) 143 channel.close() 144 145 # Step 13 146 # Verify if MBIM_OPEN_MSG request succeeds. 147 response_message = mbim_message_response.parse_response_packets( 148 response_packets) 149 150 if response_message.transaction_id != open_message.transaction_id: 151 mbim_errors.log_and_raise(mbim_errors.MBIMComplianceAssertionError, 152 'mbim1.0:9.4.1#1') 153 154 if response_message.status_codes != mbim_constants.MBIM_STATUS_SUCCESS: 155 mbim_errors.log_and_raise(mbim_errors.MBIMComplianceSequenceError, 156 'mbim1.0:9.4.1#2') 157 158 # Store data/control transfer parameters in the device context so that 159 # it can be used in any further control/data transfers. 160 device_context.max_control_transfer_size = max_control_transfer_size 161 device_context.current_ntb_format = self.get_ntb_format( 162 communication_interface_number) 163 device_context.max_in_data_transfer_size = ( 164 ntb_parameters.dwNtbInMaxSize) 165 device_context.max_out_data_transfer_size = ( 166 ntb_parameters.dwNtbOutMaxSize) 167 device_context.out_data_transfer_divisor = ( 168 ntb_parameters.wNdpOutDivisor) 169 device_context.out_data_transfer_payload_remainder = ( 170 ntb_parameters.wNdpOutPayloadRemainder) 171 device_context.out_data_transfer_ndp_alignment = ( 172 ntb_parameters.wNdpOutAlignment) 173 174 return open_message, response_message 175