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