1# Copyright 2016 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 Netgear WNR1000V4 router."""
6
7import logging
8
9import ap_spec
10import dynamic_ap_configurator
11
12
13class NetgearWNR1000V4APConfigurator(
14        dynamic_ap_configurator.DynamicAPConfigurator):
15    """Configurator for Netgear WNR1000V4 router."""
16
17
18    def get_number_of_pages(self):
19        """Returns the number of available pages."""
20        return 1
21
22
23    def is_update_interval_supported(self):
24        """
25        Returns True if setting the PSK refresh interval is supported.
26
27        @return True is supported; False otherwise.
28        """
29        return False
30
31
32    def get_supported_bands(self):
33        """Returns a list of dictionary with the supported channel per band."""
34        return [{'band': ap_spec.BAND_2GHZ,
35                 'channels': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}]
36
37
38    def get_supported_modes(self):
39        """Returns a list of dictionary with the supported band and modes."""
40        return [{'band': ap_spec.BAND_2GHZ,
41                 'modes': [ap_spec.MODE_B, ap_spec.MODE_G, ap_spec.MODE_N]}]
42
43
44    def is_security_mode_supported(self, security_mode):
45        """Returns if a given security_type is supported.
46
47        @param security_mode: one security modes defined in the APSpec.
48
49        @return True if the security mode is supported; False otherwise.
50        """
51        return security_mode in (ap_spec.SECURITY_TYPE_DISABLED,
52                                 ap_spec.SECURITY_TYPE_WPA2PSK,
53                                 ap_spec.SECURITY_TYPE_MIXED)
54
55
56    def is_spec_supported(self, spec):
57        """
58        Returns if a given spec is supported by the router.
59
60        @param spec: an instance of the
61        autotest_lib.server.cros.ap_configurators.APSpec class.
62
63        @return: True if supported. False otherwise.
64        """
65        if spec.security == ap_spec.SECURITY_TYPE_MIXED and spec.mode == ap_spec.MODE_N:
66            return False
67        return True
68
69
70    def _switch_to_frame1(self):
71        """Switch to iframe formframe."""
72        self.driver.switch_to_default_content()
73        self.wait_for_object_by_xpath('//div[@id="formframe_div"]')
74        frame = self.driver.find_element_by_xpath('//iframe[@name="formframe"]')
75        self.driver.switch_to_frame(frame)
76
77
78    def _switch_to_frame2(self):
79        """Switch to wl2gsetting iframe within formframe."""
80        self._switch_to_frame1()
81        xpath = '//div[@id="main"]//iframe[@id="2g_setting"]'
82        self.wait_for_object_by_xpath(xpath)
83        setframe = self.driver.find_element_by_xpath(xpath)
84        self.driver.switch_to_frame(setframe)
85
86
87    def _logout_from_previous_netgear_login(self):
88        """Logout if already logged into this router."""
89        self.click_button_by_id('yes')
90        self.navigate_to_page(1)
91
92
93    def navigate_to_page(self, page_number):
94        """Navigates to the page corresponding to the given page number.
95
96        This method performs the translation between a page number and a url to
97        load. This is used internally by apply_settings.
98
99        @param page_number: page number of the page to load.
100
101        """
102        if self.object_by_id_exist('yes'):
103            self._logout_from_previous_netgear_login()
104
105        self.get_url(self.admin_interface_url)
106        self.wait_for_object_by_xpath('//div[@id="wireless"]')
107        self.click_button_by_xpath('//div[@id="wireless"]')
108        self._switch_to_frame1()
109        self.wait_for_object_by_xpath('//input[@name="ssid"]')
110
111
112    def save_page(self, page_number):
113        """Saves the given page.
114
115        @param page_number: Page number of the page to save.
116        """
117        self.driver.switch_to_default_content()
118        self._switch_to_frame1()
119        xpath = '//input[@name="Apply"]'
120        self.wait_for_object_by_xpath(xpath)
121        self.click_button_by_xpath(xpath)
122        self.wait_for_object_by_xpath(xpath, wait_time=30)
123
124
125    def set_radio(self, enabled=True):
126        """Turns the radio on and off.
127
128        @param enabled: True to turn on the radio; False otherwise.
129        """
130        logging.debug('Cannot turn OFF radio!')
131
132
133    def set_ssid(self, ssid):
134        """Sets the SSID of the wireless network.
135
136        @param ssid: name of the wireless network.
137        """
138        self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)
139
140
141    def _set_ssid(self, ssid):
142        """Sets the SSID of the wireless network.
143
144        @param ssid: name of the wireless network.
145        """
146        xpath = '//input[@maxlength="32" and @name="ssid"]'
147        self.set_content_of_text_field_by_xpath(ssid, xpath, abort_check=True)
148        self._ssid = ssid
149
150
151    def set_channel(self, channel):
152        """Sets the channel of the wireless network.
153
154        @param channel: integer value of the channel.
155        """
156        self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)
157
158
159    def _set_channel(self, channel):
160        """Sets the channel of the wireless network.
161
162        @param channel: integer value of the channel.
163        """
164        position = self._get_channel_popup_position(channel)
165        channel_choices = [ '01', '02', '03', '04', '05', '06',
166                           '07', '08', '09', '10', '11']
167        xpath = '//select[@name="w_channel"]'
168        # Channel pop up is empty at this point, Save and Reload page
169        if self.number_of_items_in_popup_by_xpath(xpath) == 0:
170              self.save_page(1)
171              self._switch_to_frame2()
172              self.select_item_from_popup_by_xpath(channel_choices[position],
173                                                   xpath)
174
175
176    def set_mode(self, mode, band=None):
177        """Sets the mode.
178
179        @param mode: must be one of the modes listed in __init__().
180        @param band: the band to select.
181
182        """
183        self.add_item_to_command_list(self._set_mode, (mode,), 1, 900)
184
185
186    def _set_mode(self, mode, band=None):
187        """Sets the mode.
188
189        @param mode: must be one of the modes listed in __init__().
190        @param band: the band to select.
191
192        """
193        if mode == ap_spec.MODE_G or mode == ap_spec.MODE_B:
194            mode = 'Up to 54 Mbps'
195        elif mode == ap_spec.MODE_N:
196            mode = 'Up to 300 Mbps'
197        else:
198            raise RuntimeError('Unsupported mode passed.')
199        xpath = '//select[@name="opmode"]'
200        self.select_item_from_popup_by_xpath(mode, xpath)
201
202
203    def set_band(self, band):
204        """Sets the band of the wireless network.
205
206        @param band: Constant describing the band type.
207        """
208        self.current_band = ap_spec.BAND_2GHZ
209
210
211    def set_security_disabled(self):
212        """Disables the security of the wireless network."""
213        self.add_item_to_command_list(self._set_security_disabled, (), 1, 900)
214
215
216    def _set_security_disabled(self):
217        """Disables the security of the wireless network."""
218        self.driver.switch_to_default_content()
219        self._switch_to_frame2()
220        xpath = '//input[@name="security_type" and @value="Disable"]'
221        self.click_button_by_xpath(xpath)
222
223
224    def set_security_wep(self, value, authentication):
225        """Enables WEP security for the wireless network.
226
227        @param key_value: encryption key to use.
228        @param authentication: one of two supported WEP authentication types:
229                               open or shared.
230        """
231        logging.debug('WEP mode is not supported.')
232
233
234    def set_security_wpapsk(self, security, key, update_interval=None):
235        """Enables WPA2 and Mixed modes using a private security key for
236        the wireless network.
237
238        @param security: Required security for AP configuration.
239        @param shared_key: shared encryption key to use.
240        @param update_interval: number of seconds to wait before updating.
241        """
242        self.add_item_to_command_list(self._set_security_wpapsk,
243                                      (security, key,),
244                                      1, 900)
245
246
247    def _set_security_wpapsk(self, security, key, update_interval=None):
248        """Enables WPA2 and Mixed modes using a private security key for
249        the wireless network.
250
251        @param security: Required security for AP configuration.
252        @param shared_key: shared encryption key to use.
253        @param update_interval: number of seconds to wait before updating.
254        """
255        self._switch_to_frame2()
256
257        if security == ap_spec.SECURITY_TYPE_WPA2PSK:
258            xpath = '//input[@name="security_type" and @value="WPA2-PSK"]'
259        elif security == ap_spec.SECURITY_TYPE_MIXED:
260            xpath = '//input[@name="security_type" and @value="AUTO-PSK"]'
261        else:
262            raise RunTimeException('Invalid security mode %s sent' % security)
263
264        self.click_button_by_xpath(xpath)
265        xpath = '//input[@name="passphrase"]'
266        self.set_content_of_text_field_by_xpath(key, xpath, abort_check=True)
267
268
269    def is_visibility_supported(self):
270        """
271        Returns if AP supports setting the visibility (SSID broadcast).
272
273        @return True if supported; False otherwise.
274        """
275        return True
276
277
278    def set_visibility(self, visible=True):
279        """
280        Sets SSID broadcast ON by clicking the checkbox.
281
282        @param visible: True to enable SSID broadcast. False otherwise.
283        """
284        self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900)
285
286
287    def _set_visibility(self, visible=True):
288        """
289        Sets SSID broadcast ON by clicking the checkbox.
290
291        @param visible: True to enable SSID broadcast. False otherwise.
292        """
293        self._switch_to_frame2()
294        xpath = '//input[@name="ssid_bc" and @type="checkbox"]'
295        check_box = self.wait_for_object_by_xpath(xpath)
296        value = check_box.is_selected()
297        if (visible and not value) or (not visible and value):
298            self.click_button_by_xpath(xpath)
299