blob: 87985f4990e2a24ab4bade2ff1f7c2fcc2abcc82 [file] [log] [blame]
# Copyright (c) 2014 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.
"""
This module implements the classes for information structures encapsulated in
either |MBIMCommandMessage| or |MBIMCommandDone|.
Reference:
[1] Universal Serial Bus Communications Class Subclass Specification for
Mobile Broadband Interface Model
http://www.usb.org/developers/docs/devclass_docs/
MBIM10Errata1_073013.zip
"""
import array
import struct
import common
from autotest_lib.client.cros.cellular.mbim_compliance import mbim_control
from autotest_lib.client.cros.cellular.mbim_compliance import mbim_errors
class MBIMInformationBuffer(mbim_control.MBIMData):
"""
The base class for structures in information buffers of control messages.
"""
def __init__(self, data_buffer=None, **kwargs):
"""
@param kwargs: The keyword arguments for all the fields to be set in the
information structure body.
"""
# TODO(mcchou): The creation of |MBIMDeviceServicesInfoStructure| should
# be handled separately, since field |device_services_ref_list|
# depends on the number of |device_services_count|.
if self.__class__ is MBIMDeviceServicesInfoStructure:
mbim_errors.log_and_raise(NotImplementedError)
keys = kwargs.keys()
self.all_field_formats, self.all_field_names = zip(*self._FIELDS)
self.format_string = '<' + ''.join(self.all_field_formats)
unknown_keys = set(keys) - set(self.all_field_names)
if unknown_keys:
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceControlMessageError,
'Unknown field(s) %s found in arguments for %s.' % (
list(unknown_keys), self.__class__.__name__))
for name in self.all_field_names:
# Set the field value to the value given in |kwargs| if the value is
# provided, otherwise an error will be raised.
value = kwargs.get(name)
if value is None:
mbim_errors.log_and_raise(
mbim_errors.MBIMComplianceControlMessageError,
'Field %s is required to create a %s.' % (
name, self.__class__.__name__))
setattr(self, name, value)
setattr(self, 'data_buffer', data_buffer)
def pack(self):
"""
Pack a list of fields based on their formats.
@returns The information structure in binary array form.
"""
field_values = [getattr(self, name) for name in self.all_field_names]
byte_array = array.array('B', struct.pack(
self.format_string, *field_values))
if self.data_buffer:
byte_array.extend(self.data_buffer)
return byte_array
class MBIMSetConnectStructure(MBIMInformationBuffer):
""" The class for MBIM_SET_CONNECT structure. """
_FIELDS = (('I', 'session_id'),
('I', 'activation_command'),
('I', 'access_string_offset'),
('I', 'access_string_size'),
('I', 'user_name_offset'),
('I', 'user_name_size'),
('I', 'password_offset'),
('I', 'password_size'),
('I', 'compression'),
('I', 'auth_protocol'),
('I', 'ip_type'),
('16s', 'context_type'))
class MBIMConnectInfoStructure(MBIMInformationBuffer):
""" The class for MBIM_CONNECT_INFO structure. """
_FIELDS = (('I', 'session_id'),
('I', 'activation_state'),
('I', 'voice_call_state'),
('I', 'ip_type'),
('16s', 'context_type'),
('I', 'nw_error'))
class MBIMDeviceCapsInfoStructure(MBIMInformationBuffer):
""" The class for MBIM_DEVICE_CAPS_INFO structure. """
_FIELDS = (('I', 'device_type'),
('I', 'cellular_class'),
('I', 'voice_class'),
('I', 'sim_class'),
('I', 'data_class'),
('I', 'sms_caps'),
('I', 'control_caps'),
('I', 'max_sessions'),
('I', 'custom_data_class_offset'),
('I', 'custom_data_class_size'),
('I', 'device_id_offset'),
('I', 'device_id_size'),
('I', 'firmware_info_offset'),
('I', 'firmware_info_size'),
('I', 'hardware_info_offset'),
('I', 'hardware_info_size'))
class MBIMDeviceServicesInfoStructure(MBIMInformationBuffer):
""" The class for MBIM_DEVICE_SERVICES_INFO structure. """
# The length of |device_services_ref_list| depends on the value of
# |device_services_count|.
_FIELDS = (('I', 'device_services_count'),
('I', 'max_dss_sessions'),
('Q', 'device_services_ref_list'))
class MBIMRadioStateInfoStructure(MBIMInformationBuffer):
""" The class for MBIM_RADIO_STATE_INFO structure. """
_FIELDS = (('I', 'hw_radio_state'),
('I', 'sw_radio_state'))
class MBIMIPConfigurationInfoStructure(MBIMInformationBuffer):
""" The class for MBIM_IP_CONFIGURATION_INFO structure. """
_FIELDS = (('I', 'session_id'),
('I', 'ipv4_configuration_available'),
('I', 'ipv6_configuration_available'),
('I', 'ipv4_address_count'),
('I', 'ipv4_address_offset'),
('I', 'ipv6_address_count'),
('I', 'ipv6_address_offset'),
('I', 'ipv4_gateway_offset'),
('I', 'ipv6_gateway_offset'),
('I', 'ipv4_dns_server_count'),
('I', 'ipv4_dns_server_offset'),
('I', 'ipv6_dns_server_count'),
('I', 'ipv6_dns_server_offset'),
('I', 'ipv4_mtu'),
('I', 'ipv6_mtu'))