1 # Copyright (c) 2012 The Chromium 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 import logging 6 7 from autotest_lib.client.common_lib.cros.network import ap_constants 8 from autotest_lib.client.common_lib.cros.network import ping_runner 9 from autotest_lib.server.cros.ap_configurators import ap_spec 10 11 12 class PduNotResponding(Exception): 13 """PDU exception class.""" 14 def __init__(self, PDU): 15 self.PDU = PDU 16 logging.info('Caught PDU exception for %s', self.PDU) 17 18 def __str__(self): 19 return repr('Caught PDU exception for %s' % self.PDU) 20 21 22 class APConfiguratorAbstract(object): 23 """Abstract Base class to find and control access points.""" 24 25 def __init__(self): 26 super(APConfiguratorAbstract, self).__init__() 27 # Some APs will turn on their beacon, but the DHCP server is not 28 # running. Each configurator can add this delay to have the test 29 # wait before attempting to connect. 30 self._dhcp_delay = 0 31 32 33 @property 34 def dhcp_delay(self): 35 """Returns the DHCP delay.""" 36 return self._dhcp_delay 37 38 39 @property 40 def ssid(self): 41 """Returns the SSID.""" 42 raise NotImplementedError('Missing subclass implementation') 43 44 45 @property 46 def name(self): 47 """Returns a string to describe the router.""" 48 raise NotImplementedError('Missing subclass implementation') 49 50 51 @property 52 def configuration_success(self): 53 """Returns configuration status as defined in ap_constants""" 54 return self._configuration_success 55 56 57 @configuration_success.setter 58 def configuration_success(self, value): 59 """ 60 Set the configuration status. 61 62 @param value: the status of AP configuration. 63 64 """ 65 self._configuration_success = value 66 67 68 @property 69 def configurator_type(self): 70 """Returns the configurator type.""" 71 return ap_spec.CONFIGURATOR_STATIC 72 73 74 @property 75 def short_name(self): 76 """Returns a short string to describe the router.""" 77 raise NotImplementedError('Missing subclass implementation') 78 79 80 def check_pdu_status(self): 81 """Check if the PDU is up before making any request.""" 82 ping_options = ping_runner.PingConfig(self.pdu, count=2, 83 ignore_status=True, 84 ignore_result=True) 85 runner = ping_runner.PingRunner() 86 logging.info('Pinging rpm %s', self.pdu) 87 ping_result = runner.ping(ping_options) 88 logging.info('ping result = %s', str(ping_result)) 89 # If all ping packets failed then mark PDU down. 90 if ping_result.loss == 100: 91 self.configuration_success = ap_constants.PDU_FAIL 92 raise PduNotResponding(self.pdu) 93 94 95 def get_supported_bands(self): 96 """Returns a list of dictionaries describing the supported bands. 97 98 Example: returned is a dictionary of band and a list of channels. The 99 band object returned must be one of those defined in the 100 __init___ of this class. 101 102 supported_bands = [{'band' : self.band_2GHz, 103 'channels' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}, 104 {'band' : ap_spec.BAND_5GHZ, 105 'channels' : [26, 40, 44, 48, 149, 153, 165]}] 106 107 Note: The derived class must implement this method. 108 109 @return a list of dictionaries as described above 110 111 """ 112 raise NotImplementedError('Missing subclass implementation') 113 114 115 def get_supported_modes(self): 116 """ 117 Returns a list of dictionaries describing the supported modes. 118 119 Example: returned is a dictionary of band and a list of modes. The band 120 and modes objects returned must be one of those defined in the 121 __init___ of this class. 122 123 supported_modes = [{'band' : ap_spec.BAND_2GHZ, 124 'modes' : [mode_b, mode_b | mode_g]}, 125 {'band' : ap_spec.BAND_5GHZ, 126 'modes' : [mode_a, mode_n, mode_a | mode_n]}] 127 128 Note: The derived class must implement this method. 129 130 @return a list of dictionaries as described above 131 132 """ 133 raise NotImplementedError('Missing subclass implementation') 134 135 136 def is_visibility_supported(self): 137 """ 138 Returns if AP supports setting the visibility (SSID broadcast). 139 140 @return True if supported; False otherwise. 141 142 """ 143 return True 144 145 146 def is_band_and_channel_supported(self, band, channel): 147 """ 148 Returns if a given band and channel are supported. 149 150 @param band: the band to check if supported 151 @param channel: the channel to check if supported 152 153 @return True if combination is supported; False otherwise. 154 155 """ 156 raise NotImplementedError('Missing subclass implementation') 157 158 159 def is_security_mode_supported(self, security_mode): 160 """ 161 Returns if a given security_type is supported. 162 163 Note: The derived class must implement this method. 164 165 @param security_mode: one of the following modes: 166 self.security_disabled, 167 self.security_wep, 168 self.security_wpapsk, 169 self.security_wpa2psk 170 171 @return True if the security mode is supported; False otherwise. 172 173 """ 174 raise NotImplementedError('Missing subclass implementation') 175 176 177 178 def set_using_ap_spec(self, set_ap_spec, power_up=True): 179 """ 180 Sets all configurator options. 181 Note: The derived class may override this method. 182 183 @param set_ap_spec: APSpec object 184 @param power_up: bool, enable power via rpm if applicable 185 186 """ 187 logging.warning('%s.%s: Not Implemented', 188 self.__class__.__name__, 189 self.set_using_ap_spec.__name__) 190 191 192 def apply_settings(self): 193 """ 194 Apply all settings to the access point. 195 Note: The derived class may override this method. 196 197 """ 198 logging.warning('%s.%s: Not Implemented', 199 self.__class__.__name__, 200 self.apply_settings.__name__) 201 202 203 def get_association_parameters(self): 204 """ 205 Returns xmlrpc_datatypes.AssociationParameters for this AP 206 207 Note: The derived class must implement this method. 208 209 @return xmlrpc_datatypes.AssociationParameters 210 211 """ 212 raise NotImplementedError('Missing subclass implementation') 213 214 215 def debug_last_failure(self, outputdir): 216 """ 217 Write debug information for last AP_CONFIG_FAIL 218 219 @param outputdir: a string directory path for debug files 220 """ 221 pass 222 223 224 def debug_full_state(self, outputdir): 225 """ 226 Write debug information for full AP state 227 228 @param outputdir: a string directory path for debug files 229 """ 230 pass 231 232 233 def store_config_failure(self, trace): 234 """ 235 Store configuration failure for latter logging 236 237 @param trace: a string traceback of config exception 238 """ 239 pass 240