# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from autotest_lib.client.common_lib.cros.network import ap_constants
from autotest_lib.client.common_lib.cros.network import ping_runner
from autotest_lib.server.cros.ap_configurators import ap_spec
class PduNotResponding(Exception):
"""PDU exception class."""
def __init__(self, PDU):
self.PDU = PDU
logging.info('Caught PDU exception for %s', self.PDU)
def __str__(self):
return repr('Caught PDU exception for %s' % self.PDU)
class APConfiguratorAbstract(object):
"""Abstract Base class to find and control access points."""
def __init__(self):
super(APConfiguratorAbstract, self).__init__()
# Some APs will turn on their beacon, but the DHCP server is not
# running. Each configurator can add this delay to have the test
# wait before attempting to connect.
self._dhcp_delay = 0
@property
def dhcp_delay(self):
"""Returns the DHCP delay."""
return self._dhcp_delay
@property
def ssid(self):
"""Returns the SSID."""
raise NotImplementedError('Missing subclass implementation')
@property
def name(self):
"""Returns a string to describe the router."""
raise NotImplementedError('Missing subclass implementation')
@property
def configuration_success(self):
"""Returns configuration status as defined in ap_constants"""
return self._configuration_success
@configuration_success.setter
def configuration_success(self, value):
"""
Set the configuration status.
@param value: the status of AP configuration.
"""
self._configuration_success = value
@property
def configurator_type(self):
"""Returns the configurator type."""
return ap_spec.CONFIGURATOR_STATIC
@property
def short_name(self):
"""Returns a short string to describe the router."""
raise NotImplementedError('Missing subclass implementation')
def check_pdu_status(self):
"""Check if the PDU is up before making any request."""
ping_options = ping_runner.PingConfig(self.pdu, count=2,
ignore_status=True,
ignore_result=True)
runner = ping_runner.PingRunner()
logging.info('Pinging rpm %s', self.pdu)
ping_result = runner.ping(ping_options)
logging.info('ping result = %s', str(ping_result))
# If all ping packets failed then mark PDU down.
if ping_result.loss == 100:
self.configuration_success = ap_constants.PDU_FAIL
raise PduNotResponding(self.pdu)
def get_supported_bands(self):
"""Returns a list of dictionaries describing the supported bands.
Example: returned is a dictionary of band and a list of channels. The
band object returned must be one of those defined in the
__init___ of this class.
supported_bands = [{'band' : self.band_2GHz,
'channels' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]},
{'band' : ap_spec.BAND_5GHZ,
'channels' : [26, 40, 44, 48, 149, 153, 165]}]
Note: The derived class must implement this method.
@return a list of dictionaries as described above
"""
raise NotImplementedError('Missing subclass implementation')
def get_supported_modes(self):
"""
Returns a list of dictionaries describing the supported modes.
Example: returned is a dictionary of band and a list of modes. The band
and modes objects returned must be one of those defined in the
__init___ of this class.
supported_modes = [{'band' : ap_spec.BAND_2GHZ,
'modes' : [mode_b, mode_b | mode_g]},
{'band' : ap_spec.BAND_5GHZ,
'modes' : [mode_a, mode_n, mode_a | mode_n]}]
Note: The derived class must implement this method.
@return a list of dictionaries as described above
"""
raise NotImplementedError('Missing subclass implementation')
def is_visibility_supported(self):
"""
Returns if AP supports setting the visibility (SSID broadcast).
@return True if supported; False otherwise.
"""
return True
def is_band_and_channel_supported(self, band, channel):
"""
Returns if a given band and channel are supported.
@param band: the band to check if supported
@param channel: the channel to check if supported
@return True if combination is supported; False otherwise.
"""
raise NotImplementedError('Missing subclass implementation')
def is_security_mode_supported(self, security_mode):
"""
Returns if a given security_type is supported.
Note: The derived class must implement this method.
@param security_mode: one of the following modes:
self.security_disabled,
self.security_wep,
self.security_wpapsk,
self.security_wpa2psk
@return True if the security mode is supported; False otherwise.
"""
raise NotImplementedError('Missing subclass implementation')
def set_using_ap_spec(self, set_ap_spec, power_up=True):
"""
Sets all configurator options.
Note: The derived class may override this method.
@param set_ap_spec: APSpec object
@param power_up: bool, enable power via rpm if applicable
"""
logging.warning('%s.%s: Not Implemented',
self.__class__.__name__,
self.set_using_ap_spec.__name__)
def apply_settings(self):
"""
Apply all settings to the access point.
Note: The derived class may override this method.
"""
logging.warning('%s.%s: Not Implemented',
self.__class__.__name__,
self.apply_settings.__name__)
def get_association_parameters(self):
"""
Returns xmlrpc_datatypes.AssociationParameters for this AP
Note: The derived class must implement this method.
@return xmlrpc_datatypes.AssociationParameters
"""
raise NotImplementedError('Missing subclass implementation')
def debug_last_failure(self, outputdir):
"""
Write debug information for last AP_CONFIG_FAIL
@param outputdir: a string directory path for debug files
"""
pass
def debug_full_state(self, outputdir):
"""
Write debug information for full AP state
@param outputdir: a string directory path for debug files
"""
pass
def store_config_failure(self, trace):
"""
Store configuration failure for latter logging
@param trace: a string traceback of config exception
"""
pass