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