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