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""" 5Connect Sequence 6 7Reference: 8 [1] Universal Serial Bus Communication Class MBIM Compliance Testing: 20 9 http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf 10""" 11import array 12import common 13 14from autotest_lib.client.cros.cellular.mbim_compliance import mbim_channel 15from autotest_lib.client.cros.cellular.mbim_compliance \ 16 import mbim_command_message 17from autotest_lib.client.cros.cellular.mbim_compliance import mbim_constants 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 sequence 25 26 27class ConnectSequence(sequence.Sequence): 28 """ Implement the Connect Sequence. """ 29 30 def run_internal(self, 31 introduce_error_in_access_offset=False, 32 introduce_error_in_packets_order=None, 33 raise_exception_on_failure=True): 34 """ 35 Run the Connect Sequence. 36 37 Once the command message is sent, there should be at least one 38 notification received apart from the command done message. 39 40 @param introduce_error_in_access_offset: Whether to introduce an 41 error in the access_string offset or not. 42 @param introduce_error_in_packets_order: Whether to introduce an 43 error in the order of packets sent or not. It's a user provided 44 list of packet sequence numbers to reorder, repeat or remove 45 packets generated for connect before sending it to the device. 46 @param raise_exception_on_failure: Whether to raise an exception or not. 47 @returns tuple of (command_message, response_message, notifications): 48 command_message: The command message sent to device. 49 |command_message| is a MBIMCommandMessage object. 50 response_message: The response to the |command_message|. 51 |response_message| is a MBIMCommandDoneMessage object. 52 notifications: The list of notifications message sent from the 53 modem to the host. |notifications| is a list of 54 |MBIMIndicateStatusMessage| objects. 55 """ 56 # Step 1 57 # Send MBIM_COMMAND_MSG. 58 context_type = mbim_constants.MBIM_CONTEXT_TYPE_INTERNET.bytes 59 data_buffer = array.array('B', 'loopback'.encode('utf-16le')) 60 information_buffer_length = ( 61 mbim_command_message.MBIMSetConnect.get_struct_len()) 62 information_buffer_length += len(data_buffer) 63 device_context = self.device_context 64 descriptor_cache = device_context.descriptor_cache 65 if introduce_error_in_access_offset: 66 access_string_offset = 0 67 else: 68 access_string_offset = 60 69 command_message = ( 70 mbim_command_message.MBIMSetConnect(session_id=0, 71 activation_command=1, 72 access_string_offset=access_string_offset, 73 access_string_size=16, 74 user_name_offset=0, 75 user_name_size=0, 76 password_offset=0, 77 password_size=0, 78 compression=0, 79 auth_protocol=0, 80 ip_type=1, 81 context_type=context_type, 82 information_buffer_length=information_buffer_length, 83 payload_buffer=data_buffer)) 84 packets = mbim_message_request.generate_request_packets( 85 command_message, 86 device_context.max_control_transfer_size) 87 channel = mbim_channel.MBIMChannel( 88 device_context._device, 89 descriptor_cache.mbim_communication_interface.bInterfaceNumber, 90 descriptor_cache.interrupt_endpoint.bEndpointAddress, 91 device_context.max_control_transfer_size) 92 if introduce_error_in_packets_order is not None: 93 packets = [packets[i] for i in introduce_error_in_packets_order] 94 response_packets = channel.bidirectional_transaction(*packets) 95 notifications_packets = channel.get_outstanding_packets(); 96 channel.close() 97 98 # Step 2 99 response_message = mbim_message_response.parse_response_packets( 100 response_packets) 101 notifications = [] 102 for notification_packets in notifications_packets: 103 notifications.append( 104 mbim_message_response.parse_response_packets( 105 notification_packets)) 106 107 # Step 3 108 if (response_message.message_type != mbim_constants.MBIM_COMMAND_DONE or 109 response_message.status_codes != mbim_constants.MBIM_STATUS_SUCCESS): 110 if raise_exception_on_failure: 111 mbim_errors.log_and_raise( 112 mbim_errors.MBIMComplianceSequenceError, 113 'Connect sequence failed.') 114 115 return command_message, response_message, notifications 116