• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Belkin router."""
6
7import logging
8import os
9import time
10import urlparse
11
12import dynamic_ap_configurator
13import ap_spec
14from selenium.common.exceptions import NoSuchElementException as \
15    SeleniumNoSuchElementException
16
17
18class BelkinAPConfigurator(
19        dynamic_ap_configurator.DynamicAPConfigurator):
20    """Base class for Belkin F5D8235-4 V2 router."""
21
22
23    def _security_alert(self, alert):
24        text = alert.text
25        if "Invalid character" in text:
26            alert.accept()
27        else:
28            raise RuntimeError('Unhandled alert: %s', text)
29
30
31    def _open_landing_page(self):
32        page_url = urlparse.urljoin(self.admin_interface_url,'home.htm')
33        self.get_url(page_url, page_title='Setup Home')
34        # Do we need to login?
35        try:
36            self.driver.find_element_by_link_text('Login')
37        except SeleniumNoSuchElementException:
38            # already logged in, return
39            return
40        login_element = self.driver.find_element_by_link_text('Login')
41        login_element.click()
42        xpath = '//input[@name="www_password"]'
43        self.set_content_of_text_field_by_xpath('password', xpath,
44                                                abort_check=True)
45        self.click_button_by_id('submitBtn_submit')
46
47
48    def get_supported_bands(self):
49        return [{'band': ap_spec.BAND_2GHZ,
50                 'channels': ['Auto', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}]
51
52
53    def get_supported_modes(self):
54        return [{'band': ap_spec.BAND_2GHZ,
55                 'modes': [ap_spec.MODE_G | ap_spec.MODE_B, ap_spec.MODE_N,
56                           ap_spec.MODE_B | ap_spec.MODE_G | ap_spec.MODE_N]}]
57
58
59    def get_number_of_pages(self):
60        return 2
61
62
63    def is_security_mode_supported(self, security_mode):
64        """
65        Returns if a given security_type is supported.
66
67        @param security_mode: one security modes defined in the APSpec
68
69        @return True if the security mode is supported; False otherwise.
70
71        """
72        return security_mode in (ap_spec.SECURITY_TYPE_DISABLED,
73                                 ap_spec.SECURITY_TYPE_WPAPSK,
74                                 ap_spec.SECURITY_TYPE_WEP)
75
76
77    def navigate_to_page(self, page_number):
78        """
79        Navigates to the page corresponding to the given page number.
80
81        This method performs the translation between a page number and a url to
82        load. This is used internally by apply_settings.
83
84        @param page_number: page number of the page to load
85
86        """
87        self._open_landing_page()
88        if page_number == 1:
89            page_url = urlparse.urljoin(self.admin_interface_url,
90                                        'wireless_chan.htm')
91            self.get_url(page_url, page_title='SSID')
92        elif page_number == 2:
93            page_url = urlparse.urljoin(self.admin_interface_url,
94                                        'wireless_encrypt_64.htm')
95            self.get_url(page_url, page_title='Security')
96        else:
97            raise RuntimeError('Invalid page number passed. Number of pages '
98                               '%d, page value sent was %d' %
99                               (self.get_number_of_pages(), page_number))
100
101
102    def save_page(self, page_number):
103        """
104        Saves the given page.
105
106        @param page_number: Page number of the page to save.
107
108        """
109        self.click_button_by_id('submitBtn_apply',
110                                alert_handler=self._security_alert)
111        if os.path.basename(self.driver.current_url) == 'post.cgi':
112            # Give belkin some time to save settings.
113            time.sleep(5)
114        else:
115            raise RuntimeError('Settings not applied. Invalid page %s' %
116                               os.path.basename(self.driver.current_url))
117        if (os.path.basename(self.driver.current_url) == 'wireless_chan.htm' or
118        'wireless_encrypt_64.htm' or 'wireless_wpa_psk_wpa2_psk.htm'
119        or 'wireless_encrypt_no.htm'):
120            self.driver.find_element_by_xpath('//a[text()="Logout"]')
121            self.click_button_by_xpath('//a[text()="Logout"]')
122
123
124    def set_ssid(self, ssid):
125        self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)
126
127
128    def _set_ssid(self, ssid):
129        # Belkin does not accept special characters for SSID.
130        # Invalid character: ~!@#$%^&*()={}[]|'\":;?/.,<>-
131        xpath = '//input[@name="wl_ssid"]'
132        self.set_content_of_text_field_by_xpath(ssid, xpath, abort_check=False)
133        self._ssid = ssid
134
135
136    def set_channel(self, channel):
137        self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)
138
139
140    def _set_channel(self, channel):
141        position = self._get_channel_popup_position(channel)
142        channel_choices = ['Auto', '1', '2', '3', '4', '5', '6', '7', '8',
143                           '9', '10', '11']
144        xpath = '//select[@name="wl_channel"]'
145        self.select_item_from_popup_by_xpath(channel_choices[position], xpath)
146
147
148    def set_mode(self, mode):
149        self.add_item_to_command_list(self._set_mode, (mode,), 1, 900)
150
151
152    def _set_mode(self, mode):
153        mode_mapping = {ap_spec.MODE_G | ap_spec.MODE_B: '802.11g&802.11b',
154                        ap_spec.MODE_N: '802.11n only',
155                        ap_spec.MODE_B | ap_spec.MODE_G | ap_spec.MODE_N:
156                        '802.11b&802.11g&802.11n'}
157        mode_name = mode_mapping.get(mode)
158        if not mode_name:
159            raise RuntimeError('The mode %d not supported by router %s. ',
160                               hex(mode), self.name)
161        xpath = '//select[@name="wl_gmode"]'
162        self.select_item_from_popup_by_xpath(mode_name, xpath)
163
164
165    def set_ch_width(self, channel_width):
166        """
167        Adjusts the channel width.
168
169        @param channel_width: the channel width
170        """
171        self.add_item_to_command_list(self._set_ch_width,(channel_width,),
172                                      1, 900)
173
174
175    def _set_ch_width(self, channel_width):
176        channel_choice = ['20MHz', '20/40MHz']
177        xpath = '//select[@name="wl_cwmmode"]'
178        self.select_item_from_popup_by_xpath(channel_choice[channel_width],
179                                             xpath)
180
181
182    def set_radio(self, enabled=True):
183        logging.debug('This router (%s) does not support radio', self.name)
184        return None
185
186
187    def set_band(self, band):
188        logging.debug('This router (%s) does not support multiple bands.',
189                      self.name)
190        return None
191
192
193    def set_security_disabled(self):
194        self.add_item_to_command_list(self._set_security_disabled, (), 2, 1000)
195
196
197    def _set_security_disabled(self):
198        xpath = '//select[@name="wl_sec_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), 2, 1000)
205
206
207    def _set_security_wep(self, key_value, authentication):
208        popup = '//select[@name="wl_sec_mode"]'
209        self.wait_for_object_by_xpath(popup)
210        text_field = '//input[@name="wep64pp"]'
211        self.select_item_from_popup_by_xpath('64bit WEP', popup,
212                                             wait_for_xpath=text_field)
213        self.set_content_of_text_field_by_xpath(key_value, text_field,
214                                                abort_check=True)
215        self.click_button_by_id('submitBtn_generate')
216
217
218    def set_security_wpapsk(self, security, shared_key, update_interval=None):
219        self.add_item_to_command_list(self._set_security_wpapsk,
220                                      (shared_key, update_interval), 2, 900)
221
222
223    def _set_security_wpapsk(self, security, shared_key, update_interval=None):
224        popup = '//select[@name="wl_sec_mode"]'
225        self.wait_for_object_by_xpath(popup)
226        key_field = '//input[@name="wl_wpa_psk1"]'
227        psk = '//select[@name="wl_auth"]'
228        self.select_item_from_popup_by_xpath('WPA-PSK(no server)', popup,
229                                             wait_for_xpath=key_field)
230        self.select_item_from_popup_by_xpath('psk', psk)
231        self.set_content_of_text_field_by_xpath(shared_key, key_field,
232                                                abort_check=False)
233
234
235    def is_visibility_supported(self):
236        """
237        Returns if AP supports setting the visibility (SSID broadcast).
238
239        @return True if supported; False otherwise.
240        """
241        return False
242
243
244    def is_update_interval_supported(self):
245        """
246        Returns True if setting the PSK refresh interval is supported.
247
248        @return True is supported; False otherwise
249        """
250        return False
251