blob: 1b09533c6d0a3ee790ef9cc0f4250411d7108027 [file] [log] [blame]
import collections
import numpy
import time
from acts_contrib.test_utils.wifi.wifi_retail_ap import WifiRetailAP
from acts_contrib.test_utils.wifi.wifi_retail_ap import BlockingBrowser
BROWSER_WAIT_SHORT = 1
BROWSER_WAIT_MED = 3
BROWSER_WAIT_LONG = 10
BROWSER_WAIT_EXTRA_LONG = 60
class BrcmRefAP(WifiRetailAP):
"""Class that implements Netgear RAX200 AP.
Since most of the class' implementation is shared with the R7000, this
class inherits from NetgearR7000AP and simply redefines config parameters
"""
def __init__(self, ap_settings):
super().__init__(ap_settings)
self.init_gui_data()
# Read and update AP settings
self.read_ap_settings()
self.update_ap_settings(ap_settings)
def init_gui_data(self):
self.config_page = ('{protocol}://{username}:{password}@'
'{ip_address}:{port}/info.html').format(
protocol=self.ap_settings['protocol'],
username=self.ap_settings['admin_username'],
password=self.ap_settings['admin_password'],
ip_address=self.ap_settings['ip_address'],
port=self.ap_settings['port'])
self.config_page_nologin = (
'{protocol}://{ip_address}:{port}/'
'wlrouter/radio.asp').format(
protocol=self.ap_settings['protocol'],
ip_address=self.ap_settings['ip_address'],
port=self.ap_settings['port'])
self.capabilities = {
'interfaces': ['2G_5G', '6G'],
'channels': {
'2G_5G': [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56,
60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136,
140, 144, 149, 153, 157, 161, 165
],
'6G': ['6g' + str(ch) for ch in numpy.arange(1, 222, 4)]
},
'modes': {
'2G_5G': [
'VHT20', 'VHT40', 'VHT80', 'VHT160', 'HE20', 'HE40',
'HE80', 'HE160'
],
'6G': [
'VHT20', 'VHT40', 'VHT80', 'VHT160', 'HE20', 'HE40',
'HE80', 'HE160'
]
},
'default_mode': 'HE'
}
self.ap_settings['region'] = 'United States'
for interface in self.capabilities['interfaces']:
self.ap_settings[interface] = {
'ssid': 'BrcmAP0' if interface == '6G' else 'BrcmAP1',
'security_type': 'Open',
'password': '1234567890'
}
self.config_page_fields = collections.OrderedDict({
('2G_5G', 'interface'): ('wl_unit', 1),
('2G_5G', 'band'):
'wl_nband',
('2G_5G', 'bandwidth'):
'wl_bw_cap',
('2G_5G', 'channel'):
'wl_chanspec',
('6G', 'interface'): ('wl_unit', 0),
('6G', 'band'):
'wl_nband',
('6G', 'bandwidth'):
'wl_bw_cap',
('6G', 'channel'):
'wl_chanspec',
})
self.band_mode_values = {'1': '5 GHz', '2': '2.4 GHz', '4': '6 GHz'}
self.band_values = {'5 GHz': 1, '2.4 GHz': 2, '6 GHz': 4}
self.bandwidth_mode_values = {
'1': 'HE20',
'3': 'HE40',
'7': 'HE80',
'15': 'HE160'
}
def _decode_channel_string(self, channel_string):
if channel_string == '0':
return 'Auto'
if 'u' in channel_string or 'l' in channel_string:
channel_string = channel_string[0:-1]
elif len(channel_string.split('/')) > 1:
channel_string = channel_string.split('/')[0]
if '6g' in channel_string:
return channel_string
else:
return int(channel_string)
def _get_channel_str(self, interface, channel, bandwidth):
bandwidth = int(''.join([x for x in bandwidth if x.isdigit()]))
if bandwidth == 20:
channel_str = str(channel)
elif bandwidth in [80, 160]:
channel_str = str(channel) + '/' + str(bandwidth)
elif interface == '6G' and bandwidth == 40:
channel_str = str(channel) + '/' + str(bandwidth)
elif interface == '2G_5G' and bandwidth == 40:
lower_lookup = [
36, 44, 52, 60, 100, 108, 116, 124, 132, 140, 149, 157
]
if int(channel) in lower_lookup:
channel_str = str(channel) + 'l'
else:
channel_str = str(channel) + 'u'
return channel_str
def read_ap_settings(self):
with BlockingBrowser(self.ap_settings['headless_browser'],
900) as browser:
# Visit URL
browser.visit_persistent(self.config_page, BROWSER_WAIT_MED, 10)
browser.visit_persistent(self.config_page_nologin,
BROWSER_WAIT_MED, 10, self.config_page)
for key in self.config_page_fields.keys():
if 'interface' in key:
config_item = browser.find_by_name(
self.config_page_fields[key][0]).first
config_item.select(self.config_page_fields[key][1])
time.sleep(BROWSER_WAIT_SHORT)
else:
config_item = browser.find_by_name(
self.config_page_fields[key]).first
if 'band' in key:
self.ap_settings[key[0]][
key[1]] = self.band_mode_values[config_item.value]
elif 'bandwidth' in key:
self.ap_settings[key[0]][key[
1]] = self.bandwidth_mode_values[config_item.value]
elif 'channel' in key:
self.ap_settings[key[0]][
key[1]] = self._decode_channel_string(
config_item.value)
else:
self.ap_settings[key[0]][key[1]] = config_item.value
def update_ap_settings(self, dict_settings={}, **named_settings):
"""Function to update settings of existing AP.
Function copies arguments into ap_settings and calls configure_ap
to apply them.
Args:
dict_settings: single dictionary of settings to update
**named_settings: named settings to update
Note: dict and named_settings cannot contain the same settings.
"""
settings_to_update = dict(dict_settings, **named_settings)
if len(settings_to_update) != len(dict_settings) + len(named_settings):
raise KeyError('The following keys were passed twice: {}'.format(
(set(dict_settings.keys()).intersection(
set(named_settings.keys())))))
updating_6G = '6G' in settings_to_update.keys()
updating_2G_5G = '2G_5G' in settings_to_update.keys()
if updating_2G_5G:
if 'channel' in settings_to_update['2G_5G']:
band = '2.4 GHz' if int(
settings_to_update['2G_5G']['channel']) < 13 else '5 GHz'
if band == '2.4 GHz':
settings_to_update['2G_5G']['bandwidth'] = 'HE20'
settings_to_update['2G_5G']['band'] = band
self.ap_settings, updates_requested, status_toggle_flag = self._update_settings_dict(
self.ap_settings, settings_to_update)
if updates_requested:
self.configure_ap(updating_2G_5G, updating_6G)
def configure_ap(self, updating_2G_5G, updating_6G):
with BlockingBrowser(self.ap_settings['headless_browser'],
900) as browser:
interfaces_to_update = []
if updating_2G_5G:
interfaces_to_update.append('2G_5G')
if updating_6G:
interfaces_to_update.append('6G')
for interface in interfaces_to_update:
# Visit URL
browser.visit_persistent(self.config_page, BROWSER_WAIT_MED,
10)
browser.visit_persistent(self.config_page_nologin,
BROWSER_WAIT_MED, 10,
self.config_page)
config_item = browser.find_by_name(
self.config_page_fields[(interface, 'interface')][0]).first
config_item.select(self.config_page_fields[(interface,
'interface')][1])
time.sleep(BROWSER_WAIT_SHORT)
for key, value in self.config_page_fields.items():
if 'interface' in key or interface not in key:
continue
config_item = browser.find_by_name(
self.config_page_fields[key]).first
if 'band' in key:
config_item.select(
self.band_values[self.ap_settings[key[0]][key[1]]])
elif 'bandwidth' in key:
config_item.select_by_text(
str(self.ap_settings[key[0]][key[1]])[2:] + ' MHz')
elif 'channel' in key:
channel_str = self._get_channel_str(
interface, self.ap_settings[interface][key[1]],
self.ap_settings[interface]['bandwidth'])
config_item.select_by_text(channel_str)
else:
self.ap_settings[key[0]][key[1]] = config_item.value
time.sleep(BROWSER_WAIT_SHORT)
# Apply
config_item = browser.find_by_name('action')
config_item.first.click()
time.sleep(BROWSER_WAIT_MED)
config_item = browser.find_by_name('action')
time.sleep(BROWSER_WAIT_SHORT)
config_item.first.click()
time.sleep(BROWSER_WAIT_LONG)
browser.visit_persistent(self.config_page, BROWSER_WAIT_LONG,
10)