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