1# Copyright (c) 2012 The Chromium 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 5"""Base class for objects to configure Linksys dual band access points 6 using webdriver.""" 7 8import logging 9import urlparse 10 11import dynamic_ap_configurator 12import ap_spec 13 14class LinksyseDualBandAPConfigurator( 15 dynamic_ap_configurator.DynamicAPConfigurator): 16 """Base class for objects to configure Linksys dual band access points 17 using webdriver.""" 18 19 20 def _alert_handler(self, alert): 21 """Checks for any modal dialogs which popup to alert the user and 22 either raises a RuntimeError or ignores the alert. 23 24 Args: 25 alert: The modal dialog's contents. 26 """ 27 text = alert.text 28 # We ignore warnings that we get when we disable visibility or security 29 # changed to WEP, WPA Personal or WPA Enterprise. 30 if 'Security Mode is disabled.' in text: 31 alert.accept() 32 elif 'Your wireless security mode is not compatible with' in text: 33 alert.accept() 34 elif 'WARNING: Your Wireless-N devices will only operate ' in text: 35 alert.accept() 36 elif 'Setting the Security Mode to WEP, WPA Personal' in text: 37 alert.accept() 38 elif 'Turning off SSID Broadcast' in text: 39 alert.accept() 40 elif 'Security modes are not compatible' in text: 41 alert.accept() 42 raise RuntimeError('Security modes are not compatible. %s' % text) 43 elif 'security mode is not compatible with Wireless-N' in text: 44 alert.accept() 45 elif 'Please select WPA2-Personal or WPA2-Enterprise' in text: 46 alert.accept() 47 elif 'The wifi interface is current busy.' in text: 48 alert.accept() 49 self.click_button_by_xpath('//a[text()="Save Settings"]', 50 alert_handler=self._alert_handler) 51 else: 52 alert.accept() 53 raise RuntimeError('We have an unhandled alert: %s' % text) 54 55 56 def get_number_of_pages(self): 57 return 1 58 59 60 def get_supported_bands(self): 61 return [{'band': ap_spec.BAND_2GHZ, 62 'channels': ['Auto', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}, 63 {'band': ap_spec.BAND_5GHZ, 64 'channels': ['Auto', 36, 40, 44, 48, 149, 153, 157, 161]}] 65 66 67 def get_supported_modes(self): 68 return [{'band': ap_spec.BAND_2GHZ, 69 'modes': [ap_spec.MODE_B, ap_spec.MODE_N, ap_spec.MODE_B | 70 ap_spec.MODE_G, ap_spec.MODE_G]}, 71 {'band': ap_spec.BAND_5GHZ, 72 'modes': [ap_spec.MODE_A, ap_spec.MODE_N]}] 73 74 75 def is_security_mode_supported(self, security_mode): 76 if self.current_band == ap_spec.BAND_5GHZ: 77 return security_mode in (ap_spec.SECURITY_TYPE_DISABLED, 78 ap_spec.SECURITY_TYPE_WPAPSK, 79 ap_spec.SECURITY_TYPE_WPA2PSK) 80 return security_mode in (ap_spec.SECURITY_TYPE_DISABLED, 81 ap_spec.SECURITY_TYPE_WPAPSK, 82 ap_spec.SECURITY_TYPE_WPA2PSK, 83 ap_spec.SECURITY_TYPE_WEP) 84 85 86 def navigate_to_page(self, page_number): 87 if page_number == 1: 88 url = urlparse.urljoin(self.admin_interface_url, 89 'Wireless_Basic.asp') 90 self.get_url(url, page_title='Settings') 91 else: 92 raise RuntimeError('Invalid page number passed. Number of pages ' 93 '%d, page value sent was %d' % 94 (self.get_number_of_pages(), page_number)) 95 96 97 def save_page(self, page_number): 98 self.click_button_by_xpath('//a[text()="Save Settings"]', 99 alert_handler=self._alert_handler) 100 continue_xpath = '//input[@value="Continue" and @type="button"]' 101 self.wait_for_object_by_xpath(continue_xpath) 102 self.click_button_by_xpath(continue_xpath) 103 104 105 def set_mode(self, mode, band=None): 106 self.add_item_to_command_list(self._set_mode, (mode, band), 1, 800) 107 108 109 def _set_mode(self, mode, band=None): 110 mode_mapping = {ap_spec.MODE_B: 'Wireless-B Only', 111 ap_spec.MODE_G: 'Wireless-G Only', 112 ap_spec.MODE_B | ap_spec.MODE_G: 'Wireless-B/G Only', 113 ap_spec.MODE_N: 'Wireless-N Only', 114 ap_spec.MODE_A: 'Wireless-A Only'} 115 xpath = '//select[@name="wl0_net_mode"]' 116 if self.current_band == ap_spec.BAND_5GHZ or band == ap_spec.BAND_5GHZ: 117 self.current_band = ap_spec.BAND_5GHZ 118 xpath = '//select[@name="wl1_net_mode"]' 119 mode_name = '' 120 if mode in mode_mapping.keys(): 121 mode_name = mode_mapping[mode] 122 if ((mode & ap_spec.MODE_A) and 123 (self.current_band != ap_spec.BAND_5GHZ)): 124 # a mode only in 5Ghz 125 logging.debug('Mode \'a\' is not available for 2.4Ghz band.') 126 return 127 elif ((mode & (ap_spec.MODE_B | ap_spec.MODE_G) == 128 (ap_spec.MODE_B | ap_spec.MODE_G)) or 129 (mode & ap_spec.MODE_B == ap_spec.MODE_B) or 130 (mode & ap_spec.MODE_G == ap_spec.MODE_G)) and \ 131 (self.current_band != ap_spec.BAND_2GHZ): 132 # b/g, b, g mode only in 2.4Ghz 133 logging.debug('Mode \'%s\' is not available for 5Ghz band.', 134 mode_name) 135 return 136 else: 137 raise RuntimeError('The mode selected %d is not supported by router' 138 ' %s.', hex(mode), self.name) 139 self.select_item_from_popup_by_xpath(mode_name, xpath, 140 alert_handler=self._alert_handler) 141 142 143 def set_radio(self, enabled=True): 144 logging.debug('set_radio is not supported in Linksys dual band AP.') 145 return None 146 147 148 def set_ssid(self, ssid): 149 self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900) 150 151 152 def _set_ssid(self, ssid): 153 xpath = '//input[@maxlength="32" and @name="wl0_ssid"]' 154 if self.current_band == ap_spec.BAND_5GHZ: 155 xpath = '//input[@maxlength="32" and @name="wl1_ssid"]' 156 self.set_content_of_text_field_by_xpath(ssid, xpath) 157 self._ssid = ssid 158 159 160 def set_channel(self, channel): 161 self.add_item_to_command_list(self._set_channel, (channel,), 1, 900) 162 163 164 def _set_channel(self, channel): 165 position = self._get_channel_popup_position(channel) 166 channel_choices = ['Auto', 167 '1 - 2.412 GHz', '2 - 2.417 GHz', '3 - 2.422 GHz', 168 '4 - 2.427 GHz', '5 - 2.432 GHz', '6 - 2.437 GHz', 169 '7 - 2.442 GHz', '8 - 2.447 GHz', '9 - 2.452 GHz', 170 '10 - 2.457 GHz', '11 - 2.462 GHz'] 171 xpath = '//select[@name="_wl0_channel"]' 172 if self.current_band == ap_spec.BAND_5GHZ: 173 xpath = '//select[@name="_wl1_channel"]' 174 channel_choices = ['Auto', '36 - 5.180 GHz', '40 - 5.200 GHz', 175 '44 - 5.220 GHz', '48 - 5.240 GHz', 176 '149 - 5.745 GHz', '153 - 5.765 GHz', 177 '157 - 5.785 GHz', '161 - 5.805 GHz'] 178 self.select_item_from_popup_by_xpath(channel_choices[position], 179 xpath) 180 181 182 def set_band(self, band): 183 if band == ap_spec.BAND_5GHZ: 184 self.current_band = ap_spec.BAND_5GHZ 185 elif band == ap_spec.BAND_2GHZ: 186 self.current_band = ap_spec.BAND_2GHZ 187 else: 188 raise RuntimeError('Invalid band sent %s' % band) 189 190 191 def set_security_disabled(self): 192 self.add_item_to_command_list(self._set_security_disabled, (), 1, 900) 193 194 195 def _set_security_disabled(self): 196 xpath = '//select[@name="wl0_security_mode"]' 197 if self.current_band == ap_spec.BAND_5GHZ: 198 xpath = '//select[@name="wl1_security_mode"]' 199 self.select_item_from_popup_by_xpath('Disabled', xpath) 200 201 202 def set_security_wep(self, key_value, authentication): 203 self.add_item_to_command_list(self._set_security_wep, 204 (key_value, authentication), 1, 900) 205 206 207 def _set_security_wep(self, key_value, authentication): 208 popup = '//select[@name="wl0_security_mode"]' 209 text_field = '//input[@name="wl0_passphrase"]' 210 xpath = '//input[@name="wepGenerate0" and @type="button"]' 211 if self.current_band == ap_spec.BAND_5GHZ: 212 popup = '//select[@name="wl1_security_mode"]' 213 text_field = '//input[@name="wl1_passphrase"]' 214 xpath = '//input[@name="wepGenerate1" and @type="button"]' 215 self.wait_for_object_by_xpath(popup) 216 self.select_item_from_popup_by_xpath('WEP', popup, 217 wait_for_xpath=text_field, 218 alert_handler=self._alert_handler) 219 self.set_content_of_text_field_by_xpath(key_value, text_field, 220 abort_check=True) 221 self.click_button_by_xpath(xpath) 222 223 224 def set_security_wpapsk(self, security, shared_key, update_interval=None): 225 self.add_item_to_command_list(self._set_security_wpapsk, 226 (security, shared_key, update_interval), 227 1, 900) 228 229 230 def _set_security_wpapsk(self, security, shared_key, update_interval=None): 231 popup = '//select[@name="wl0_security_mode"]' 232 key_field = '//input[@name="wl0_wpa_psk"]' 233 if self.current_band == ap_spec.BAND_5GHZ: 234 popup = '//select[@name="wl1_security_mode"]' 235 key_field = '//input[@name="wl1_wpa_psk"]' 236 self.wait_for_object_by_xpath(popup) 237 if security == ap_spec.SECURITY_TYPE_WPAPSK: 238 wpa_item = 'WPA Personal' 239 else: 240 wpa_item = 'WPA2 Personal' 241 self.select_item_from_popup_by_xpath(wpa_item, popup, 242 wait_for_xpath=key_field, 243 alert_handler=self._alert_handler) 244 self.set_content_of_text_field_by_xpath(shared_key, key_field, 245 abort_check=True) 246 247 248 def is_update_interval_supported(self): 249 """ 250 Returns True if setting the PSK refresh interval is supported. 251 252 @return True is supported; False otherwise 253 """ 254 return False 255 256 257 def set_visibility(self, visible=True): 258 self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900) 259 260 261 def _set_visibility(self, visible=True): 262 button = 'wl0_closed' 263 if self.current_band == ap_spec.BAND_5GHZ: 264 button = 'wl1_closed' 265 int_value = 0 if visible else 1 266 xpath = ('//input[@value="%d" and @name="%s"]' % (int_value, button)) 267 self.click_button_by_xpath(xpath) 268