1# Copyright (c) 2012 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 5import ConfigParser 6import logging 7import os 8import time 9 10from autotest_lib.client.common_lib.cros.network import ap_constants 11from autotest_lib.site_utils.rpm_control_system import rpm_client 12from autotest_lib.server.cros.ap_configurators import ap_spec 13 14# chaos_shadow_ap_list.conf is used for testing against local APs. 15AP_CONFIG_FILES = { ap_constants.AP_TEST_TYPE_CHAOS: 16 ('chaos_ap_list.conf', 17 'chaos_shadow_ap_list.conf'),} 18 19TIMEOUT = 100 20 21def get_ap_list(ap_test_type): 22 """ 23 Returns the list of AP's from the corresponding configuration file. 24 25 @param ap_test_type: Used to determine which type of test we're 26 currently running (Chaos vs Clique). 27 @returns a list of AP objects. 28 29 """ 30 aps = [] 31 ap_config_files = AP_CONFIG_FILES.get(ap_test_type, None) 32 for filename in ap_config_files: 33 ap_config = ConfigParser.RawConfigParser( 34 {AP.CONF_RPM_MANAGED: 'False'}) 35 path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 36 filename) 37 if not os.path.exists(path): 38 logging.warning('Skipping missing config: "%s"', path) 39 continue 40 41 logging.debug('Reading config from: "%s"', path) 42 ap_config.read(path) 43 for bss in ap_config.sections(): 44 aps.append(AP(bss, ap_config)) 45 return aps 46 47 48class APPowerException(Exception): 49 """ Exception raised when AP fails to power on. """ 50 pass 51 52class APSectionError(Exception): 53 """ Exception raised when AP instance does not exist in the config. """ 54 pass 55 56class AP(object): 57 """ An instance of an ap defined in the chaos config file. 58 59 This object is a wrapper that can be used to retrieve information 60 about an AP in the chaos lab, and control its power. 61 62 """ 63 64 65 # Keys used in the config file. 66 CONF_SSID = 'ssid' 67 CONF_BRAND = 'brand' 68 CONF_MODEL = 'model' 69 CONF_WAN_MAC = 'wan mac' 70 CONF_WAN_HOST = 'wan_hostname' 71 CONF_RPM_MANAGED = 'rpm_managed' 72 CONF_BSS = 'bss' 73 CONF_BSS5 = 'bss5' 74 CONF_BANDWIDTH = 'bandwidth' 75 CONF_SECURITY = 'security' 76 CONF_PSK = 'psk' 77 CONF_FREQUENCY = 'frequency' 78 CONF_BAND = 'band' 79 CONF_CHANNEL = 'channel' 80 CONF_CLASS = 'class_name' 81 CONF_ADMIN = 'admin_url' 82 CONF_ADMIN_IP = 'admin_ip' 83 84 85 def __init__(self, bss, config): 86 """ 87 Intialize object 88 89 @param bss: string containing bssid 90 @param config: ConfigParser read from file 91 92 """ 93 if not config.has_section(bss): 94 raise APSectionError('BSS (%s) not defined.' % bss) 95 self.bss = bss 96 self.ap_config = config 97 98 99 def get_ssid(self): 100 """@return string ssid for AP from config file""" 101 return self.ap_config.get(self.bss, self.CONF_SSID) 102 103 104 def get_brand(self): 105 """@return string brand for AP from config file""" 106 return self.ap_config.get(self.bss, self.CONF_BRAND) 107 108 109 def get_model(self): 110 """@return string model for AP from config file""" 111 return self.ap_config.get(self.bss, self.CONF_MODEL) 112 113 114 def get_wan_mac(self): 115 """@return string mac for WAN port of AP from config file""" 116 return self.ap_config.get(self.bss, self.CONF_WAN_MAC) 117 118 119 def get_wan_host(self): 120 """@return string host for AP from config file""" 121 return self.ap_config.get(self.bss, self.CONF_WAN_HOST) 122 123 124 def get_rpm_managed(self): 125 """@return bool for AP power via rpm from config file""" 126 return self.ap_config.getboolean(self.bss, self.CONF_RPM_MANAGED) 127 128 129 def get_bss(self): 130 """@return string bss for AP from config file""" 131 try: 132 bss = self.ap_config.get(self.bss, self.CONF_BSS) 133 except ConfigParser.NoOptionError as e: 134 bss = 'N/A' 135 return bss 136 137 138 def get_bss5(self): 139 """@return string bss5 for AP from config file""" 140 try: 141 bss5 = self.ap_config.get(self.bss, self.CONF_BSS5) 142 except ConfigParser.NoOptionError as e: 143 bss5 = 'N/A' 144 return bss5 145 146 def get_bandwidth(self): 147 """@return string bandwidth for AP from config file""" 148 return self.ap_config.get(self.bss, self.CONF_BANDWIDTH) 149 150 151 def get_security(self): 152 """@return string security for AP from config file""" 153 return self.ap_config.get(self.bss, self.CONF_SECURITY) 154 155 156 def get_psk(self): 157 """@return string psk for AP from config file""" 158 return self.ap_config.get(self.bss, self.CONF_PSK) 159 160 161 def get_frequency(self): 162 """@return int frequency for AP from config file""" 163 return int(self.ap_config.get(self.bss, self.CONF_FREQUENCY)) 164 165 def get_channel(self): 166 """@return int channel for AP from config file""" 167 return ap_spec.CHANNEL_TABLE[self.get_frequency()] 168 169 170 def get_band(self): 171 """@return string band for AP from config file""" 172 if self.get_frequency() < 4915: 173 return ap_spec.BAND_2GHZ 174 else: 175 return ap_spec.BAND_5GHZ 176 177 178 def get_class(self): 179 """@return string class for AP from config file""" 180 return self.ap_config.get(self.bss, self.CONF_CLASS) 181 182 183 def get_admin(self): 184 """@return string admin for AP from config file""" 185 return self.ap_config.get(self.bss, self.CONF_ADMIN) 186 187 188 def get_admin_ip(self): 189 """@return admin IP for AP from config file""" 190 return self.ap_config.get(self.bss, self.CONF_ADMIN_IP) 191 192 193 def power_off(self): 194 """call rpm_client to power off AP""" 195 rpm_client.set_power_afe(self.get_wan_host(), 'OFF') 196 197 198 def power_on(self): 199 """call rpm_client to power on AP""" 200 rpm_client.set_power_afe(self.get_wan_host(), 'ON') 201 202 # Hard coded timer for now to wait for the AP to come alive 203 # before trying to use it. We need scanning code 204 # to scan until the AP becomes available (crosbug.com/36710). 205 time.sleep(TIMEOUT) 206 207 208 def __str__(self): 209 """@return string description of AP""" 210 ap_info = { 211 'brand': self.get_brand(), 212 'model': self.get_model(), 213 'ssid' : self.get_ssid(), 214 'bss' : self.get_bss(), 215 'hostname': self.get_wan_host(), 216 } 217 return ('AP Info:\n' 218 ' Name: %(brand)s %(model)s\n' 219 ' SSID: %(ssid)s\n' 220 ' BSS: %(bss)s\n' 221 ' Hostname: %(hostname)s\n' % ap_info) 222