Home | History | Annotate | Download | only in ap_configurators
      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 """Class to control the BuffaloAP router."""
      6 
      7 import logging
      8 import time
      9 import urlparse
     10 
     11 import dynamic_ap_configurator
     12 import ap_spec
     13 from selenium.common.exceptions import TimeoutException as \
     14     SeleniumTimeoutException
     15 
     16 
     17 class BuffaloAPConfigurator(
     18         dynamic_ap_configurator.DynamicAPConfigurator):
     19     """Configurator for Buffalo AP."""
     20 
     21 
     22     def __init__(self, ap_config):
     23         super(BuffaloAPConfigurator, self).__init__(ap_config)
     24         self._dhcp_delay = 30
     25 
     26 
     27     def get_number_of_pages(self):
     28         return 2
     29 
     30 
     31     def is_update_interval_supported(self):
     32         """
     33         Returns True if setting the PSK refresh interval is supported.
     34 
     35         @return True is supported; False otherwise
     36         """
     37         return True
     38 
     39 
     40     def get_supported_modes(self):
     41         return [{'band':ap_spec.BAND_2GHZ,
     42                  'modes':[ap_spec.MODE_B, ap_spec.MODE_G, ap_spec.MODE_N,
     43                           ap_spec.MODE_B | ap_spec.MODE_G,
     44                           ap_spec.MODE_N | ap_spec.MODE_G]}]
     45 
     46 
     47     def get_supported_bands(self):
     48         return [{'band':ap_spec.BAND_2GHZ,
     49                  'channels':[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}]
     50 
     51 
     52     def is_security_mode_supported(self, security_mode):
     53         """
     54         Returns if a given security_type is supported.
     55 
     56         @param security_mode: one security modes defined in the APSpec
     57 
     58         @return True if the security mode is supported; False otherwise.
     59 
     60         """
     61         return security_mode in (ap_spec.SECURITY_TYPE_DISABLED,
     62                                  ap_spec.SECURITY_TYPE_WPAPSK,
     63                                  ap_spec.SECURITY_TYPE_WPA2PSK,
     64                                  ap_spec.SECURITY_TYPE_WEP)
     65 
     66 
     67     def navigate_to_page(self, page_number):
     68         """
     69         Navigates to the page corresponding to the given page number.
     70 
     71         This method performs the translation between a page number and a url to
     72         load. This is used internally by apply_settings.
     73 
     74         @param page_number: page number of the page to load
     75 
     76         """
     77         if page_number == 1:
     78            page_url = urlparse.urljoin(self.admin_interface_url,
     79                                        'Wireless_Basic.asp')
     80            self.get_url(page_url, page_title='DD-WRT')
     81         elif page_number == 2:
     82            page_url = urlparse.urljoin(self.admin_interface_url,
     83                                        'WL_WPATable.asp')
     84            self.get_url(page_url, page_title='DD-WRT')
     85         else:
     86            raise RuntimeError('Invalid page number passed. Number of pages '
     87                               '%d, page value sent was %d' %
     88                               (self.get_number_of_pages(), page_number))
     89 
     90 
     91     def save_page(self, page_number):
     92         """
     93         Saves the given page.
     94 
     95         @param page_number: Page number of the page to save.
     96 
     97         """
     98         apply_set = '//input[@name="apply_button"]'
     99         try:
    100             self.wait_for_object_by_xpath(apply_set, wait_time=30)
    101         except SeleniumTimeoutException as e:
    102             self.driver.refresh()
    103             self.wait_for_object_by_xpath(apply_set, wait_time=30)
    104         self.click_button_by_xpath(apply_set)
    105         timeout = 0
    106         while self.object_by_xpath_exist("ddwrt_message") and timeout < 60:
    107             time.sleep(1)
    108             timeout = timeout + 1
    109         self._retry_page(page_number)
    110 
    111 
    112     def _retry_page(self, page_number):
    113         """Sometimes the interface goes down, retry."""
    114         for i in range(3):
    115             if self.driver.title.find('DD-WRT') == -1:
    116                 self.navigate_to_page(page_number)
    117             else:
    118                 return
    119 
    120     def _wait_for_item_in_popup(self, item, popup):
    121         """Wait for the popup to be enumerated."""
    122         for i in range(3):
    123             self.wait_for_object_by_xpath(popup)
    124             if self.item_in_popup_by_xpath_exist(item, popup):
    125                 break
    126             else:
    127                 time.sleep(1)
    128 
    129 
    130     def set_mode(self, mode, band=None):
    131         self.add_item_to_command_list(self._set_mode, (mode,), 1, 900)
    132 
    133 
    134     def _set_mode(self, mode):
    135         # Bands are not supported, so ignore.
    136         # Create the mode to popup item mapping.
    137         mode_mapping = {ap_spec.MODE_B:'B-Only', ap_spec.MODE_G: 'G-Only',
    138                         ap_spec.MODE_N:'N-Only (2.4 GHz)',
    139                         ap_spec.MODE_M:'Mixed',
    140                         ap_spec.MODE_B | ap_spec.MODE_G:'BG-Mixed',
    141                         ap_spec.MODE_N | ap_spec.MODE_G:'NG-Mixed'}
    142         mode_name = ''
    143         if mode in mode_mapping:
    144             mode_name = mode_mapping[mode]
    145         else:
    146             raise RuntimeError('The mode %d not supported by router %s. ',
    147                                hex(mode), self.name)
    148         xpath = '//select[@name="ath0_net_mode"]'
    149         try:
    150             self.select_item_from_popup_by_xpath(mode_name, xpath)
    151         except SeleniumTimeoutException, e:
    152             self.driver.refresh()
    153             self.select_item_from_popup_by_xpath(mode_name, xpath)
    154 
    155 
    156     def set_radio(self, enabled):
    157         #  We cannot turn off radio on Buffalo.
    158         logging.debug('This router (%s) does not support radio.', self.name)
    159         return None
    160 
    161 
    162     def set_ssid(self, ssid):
    163         self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)
    164 
    165 
    166     def _set_ssid(self, ssid):
    167         xpath = '//input[@maxlength="32" and @name="ath0_ssid"]'
    168         self.set_content_of_text_field_by_xpath(ssid, xpath)
    169         self._ssid = ssid
    170 
    171 
    172     def set_channel(self, channel):
    173         self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)
    174 
    175 
    176     def _set_channel(self, channel):
    177         position = self._get_channel_popup_position(channel)
    178         channel_choices = ['1 - 2412 MHz', '2 - 2417 MHz', '3 - 2422 MHz',
    179                            '4 - 2427 MHz', '5 - 2432 MHz', '6 - 2437 MHz',
    180                            '7 - 2442 MHz', '8 - 2447 MHz', '9 - 2452 MHz',
    181                            '10 - 2457 MHz', '11 - 2462 MHz']
    182         xpath = '//select[@name="ath0_channel"]'
    183         if self.number_of_items_in_popup_by_xpath(xpath) == 0:
    184             # If the popup is empty, refresh.
    185             self.driver.refresh()
    186         self.select_item_from_popup_by_xpath(channel_choices[position], xpath)
    187 
    188 
    189     def set_ch_width(self, channel_width):
    190         """
    191         Adjusts the channel channel width.
    192 
    193         @param channel_width: the channel width
    194         """
    195         self.add_item_to_command_list(self._set_ch_width,(channel_width,), 1,
    196                                       900)
    197 
    198 
    199     def _set_ch_width(self, channel_width):
    200         channel_width_choice=['Full (20 MHz)', 'Half (10 MHz)',
    201                               'Quarter (5 MHz)']
    202         xpath = '//select[@name="ath0_channelbw"]'
    203         self.select_item_from_popup_by_xpath(
    204             channel_width_choice[channel_width], xpath)
    205 
    206 
    207     def set_wireless_mode(self, wireless_mo):
    208         """
    209         Queues a change to the wireless mode.
    210 
    211         @param wireless_mo: the wireless mode.
    212         """
    213         self.add_item_to_command_list(self._set_wireless_mode,
    214                                       (wireless_mo,), 1, 900)
    215 
    216 
    217     def _set_wireless_mode(self, wireless_mo):
    218         """
    219         Sets the wireless mode.
    220 
    221         @param wireless_mo: the wireless mode.
    222         """
    223         wireless_mode_choices = ['AP', 'Client', 'Client Bridge',
    224                                  'Adhoc', 'WDS Station', 'WDS AP']
    225         xpath = '//select[@name="ath0_mode"]'
    226         self.select_item_from_popup_by_xpath(wireless_mode_choices[wireless_mo],
    227                                              xpath)
    228 
    229 
    230     def set_band(self, band):
    231         logging.debug('This router (%s) does not support multiple bands.',
    232                       self.name)
    233         return None
    234 
    235 
    236     def set_security_disabled(self):
    237         self.add_item_to_command_list(self._set_security_disabled, (), 2, 1000)
    238 
    239 
    240     def _set_security_disabled(self):
    241         self._retry_page(2)
    242 
    243         popup = '//select[@name="ath0_security_mode"]'
    244         disabled_item = 'Disabled'
    245 
    246         self._wait_for_item_in_popup(disabled_item, popup)
    247 
    248         self.select_item_from_popup_by_xpath(disabled_item, popup)
    249 
    250         for i in range(3):
    251             if (self.object_by_xpath_exist('//input[@name="ath0_passphrase"]')
    252                 or self.object_by_xpath_exist('//input[@name="ath0_wpa_psk"]')):
    253                 time.sleep(1)
    254             else:
    255                 break
    256 
    257 
    258     def set_security_wep(self, key_value, authentication):
    259         self.add_item_to_command_list(self._set_security_wep,
    260                                       (key_value, authentication), 2, 1000)
    261 
    262 
    263     def _set_security_wep(self, key_value, authentication):
    264         # Buffalo supports WEP with wireless network mode N.
    265         # No exception is thrown for N-mode with WEP security.
    266         self._retry_page(2)
    267 
    268         popup = '//select[@name="ath0_security_mode"]'
    269         text_field = '//input[@name="ath0_passphrase"]'
    270         wep_item = 'WEP'
    271 
    272         self._wait_for_item_in_popup(wep_item, popup)
    273 
    274         self.select_item_from_popup_by_xpath('WEP', popup,
    275                                              wait_for_xpath=text_field)
    276         self.wait_for_object_by_xpath(text_field)
    277         self.set_content_of_text_field_by_xpath(key_value, text_field,
    278                                                 abort_check=True)
    279         self.click_button_by_xpath('//input[@value="Generate"]')
    280 
    281 
    282     def set_security_wpapsk(self, security, shared_key, update_interval=3600):
    283         self.add_item_to_command_list(self._set_security_wpapsk,
    284                                       (security, shared_key, update_interval),
    285                                        2, 900)
    286 
    287 
    288     def _set_security_wpapsk(self, security, shared_key, update_interval=3600):
    289         self._retry_page(2)
    290         popup = '//select[@name="ath0_security_mode"]'
    291         key_field = '//input[@name="ath0_wpa_psk"]'
    292         interval_field = '//input[@name="ath0_wpa_gtk_rekey"]'
    293         if security == ap_spec.SECURITY_TYPE_WPAPSK:
    294              wpa_item = 'WPA Personal'
    295         else:
    296              wpa_item = 'WPA2 Personal'
    297         self._wait_for_item_in_popup(wpa_item, popup)
    298         self.select_item_from_popup_by_xpath(wpa_item, popup)
    299         self.wait_for_object_by_xpath(key_field, wait_time=30)
    300         self.set_content_of_text_field_by_xpath(shared_key, key_field)
    301         self.wait_for_object_by_xpath(interval_field)
    302         self.set_content_of_text_field_by_xpath(str(update_interval),
    303                                                 interval_field)
    304 
    305 
    306     def set_visibility(self, visible=True):
    307         self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900)
    308 
    309 
    310     def _set_visibility(self, visible=True):
    311         int_value = 0 if visible else 1
    312         xpath = '//input[@value="%d" and @name="ath0_closed"]' % int_value
    313         self.click_button_by_xpath(xpath)
    314