1# Copyright (c) 2014 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 Dlink DWL2100 router."""
6
7import logging
8import time
9
10import ap_spec
11import dynamic_ap_configurator
12
13class DLinkDWL2100APConfigurator(
14        dynamic_ap_configurator.DynamicAPConfigurator):
15    """Derived class to conrol DLink DWL2100 AP."""
16
17    def get_number_of_pages(self):
18        return 1
19
20
21    def get_supported_bands(self):
22        """Returns a list of dictionaries describing the supported bands.
23
24        Example: returned is a dictionary of band and a list of channels. The
25                 band object returned must be one of those defined in the
26                 __init___ of this class.
27
28        supported_bands = [{'band' : self.band_2GHz,
29                            'channels' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]},
30                           {'band' : ap_spec.BAND_5GHZ,
31                            'channels' : [26, 40, 44, 48, 149, 153, 165]}]
32
33        Note: The derived class must implement this method.
34
35        @return a list of dictionaries as described above
36
37        """
38        return [{'band': ap_spec.BAND_2GHZ,
39                 'channels': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}]
40
41
42    def get_supported_modes(self):
43        """
44        Returns a list of dictionaries describing the supported modes.
45
46        Example: returned is a dictionary of band and a list of modes. The band
47                 and modes objects returned must be one of those defined in the
48                 __init___ of this class.
49
50        supported_modes = [{'band' : ap_spec.BAND_2GHZ,
51                            'modes' : [mode_b, mode_b | mode_g]},
52                           {'band' : ap_spec.BAND_5GHZ,
53                            'modes' : [mode_a, mode_n, mode_a | mode_n]}]
54
55        Note: The derived class must implement this method.
56
57        @return a list of dictionaries as described above
58
59        """
60        return [{'band': ap_spec.BAND_2GHZ,
61                 'modes': [ap_spec.MODE_G]}]
62
63
64    def is_security_mode_supported(self, security_mode):
65        """
66        Returns if a given security_type is supported.
67
68        Note: The derived class must implement this method.
69
70        @param security_mode: one of the following modes:
71                         self.security_disabled,
72                         self.security_wep,
73                         self.security_wpapsk,
74                         self.security_wpa2psk
75
76        @return True if the security mode is supported; False otherwise.
77
78        """
79        return security_mode in (ap_spec.SECURITY_TYPE_DISABLED,
80                                 ap_spec.SECURITY_TYPE_WPAPSK,
81                                 ap_spec.SECURITY_TYPE_WPA2PSK)
82
83
84    def navigate_to_page(self, page_number):
85        """
86        Navigates to the page corresponding to the given page number.
87
88        This method performs the translation between a page number and a url to
89        load. This is used internally by apply_settings.
90
91        Note: The derived class must implement this method.
92
93        @param page_number: page number of the page to load
94
95        """
96        page_url = self.admin_interface_url
97        self.get_url(page_url, page_title='DWL-2100AP')
98        wireless_xpath = ("//html/body/table/tbody/tr[2]/td/table/tbody/tr[3]"
99                          "/td[1]/table/tbody/tr[2]/td[@class='style1']")
100        self.click_button_by_xpath(wireless_xpath)
101        # We wait for the page to load and avoid the intermediate page
102        found_id = self.wait_for_objects_by_id(['AuthMenu'],
103                                               wait_time=30)
104        if 'AuthMenu' not in found_id:
105            raise RuntimeError(
106                    'Unable to navigate to configuration page.')
107
108
109    def save_page(self, page_number):
110        """
111        Saves the given page.
112
113        Note: The derived class must implement this method.
114
115        @param page_number: Page number of the page to save.
116
117        """
118        self.driver.execute_script('formSubmit(0);')
119        count_time = '//input[@name="V_Count_Time"]'
120        timer = self.wait_for_object_by_xpath(count_time)
121        while (self.wait_for_object_by_xpath(count_time) and
122               int(timer.get_attribute('value')) > 2):
123            time.sleep(1)
124
125
126    def set_mode(self, mode, band=None):
127        """
128        Sets the mode.
129
130        Note: The derived class must implement this method.
131
132        @param mode: must be one of the modes listed in __init__()
133        @param band: the band to select
134
135        """
136        logging.debug('This router (%s) does not support multiple modes.',
137                      self.name)
138        return None
139
140
141    def set_radio(self, enabled=True):
142        """
143        Turns the radio on and off.
144
145        Note: The derived class must implement this method.
146
147        @param enabled: True to turn on the radio; False otherwise
148
149        """
150        logging.debug('This AP does not supported disabling the radio.')
151        return None
152
153
154    def set_ssid(self, ssid):
155        """
156        Sets the SSID of the wireless network.
157
158        Note: The derived class must implement this method.
159
160        @param ssid: name of the wireless network
161
162        """
163        self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)
164
165
166    def _set_ssid(self, ssid):
167        self._ssid = ssid
168        self.set_content_of_text_field_by_id(self._ssid, 'Ssid')
169
170
171    def set_channel(self, channel):
172        """
173        Sets the channel of the wireless network.
174
175        Note: The derived class must implement this method.
176
177        @param channel: integer value of the channel
178
179        """
180        self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)
181
182
183    def _set_channel(self, channel):
184        position = self._get_channel_popup_position(channel)
185        channel_choices = ['1 ', '2', '3', '4', '5', '6', '7',
186                           '8', '9', '10', '11']
187        channel_popup = self.driver.find_element_by_id('Channel')
188        self.select_item_from_popup_by_id(channel_choices[position],
189                                          'Channel')
190
191
192    def set_band(self, band):
193        """
194        Sets the band of the wireless network.
195
196        Currently there are only two possible values for band: 2kGHz and 5kGHz.
197        Note: The derived class must implement this method.
198
199        @param band: Constant describing the band type
200
201        """
202        logging.debug('This router (%s) does not support multiple bands.',
203                      self.name)
204        return None
205
206
207    def set_security_disabled(self):
208        """
209        Disables the security of the wireless network.
210
211        Note: The derived class must implement this method.
212
213        """
214        self.add_item_to_command_list(self._set_security_disabled, (), 1, 900)
215
216
217    def _set_security_disabled(self):
218        self.select_item_from_popup_by_id('Open System', 'AuthMenu')
219        self.click_button_by_id('DisableEncryption')
220
221
222    def set_security_wep(self, key_value, authentication):
223        """
224        Enabled WEP security for the wireless network.
225
226        Note: The derived class must implement this method.
227
228        @param key_value: encryption key to use
229        @param authentication: one of two supported WEP authentication types:
230                               open or shared.
231        """
232        logging.debug('This router (%s) does not support WEP.',
233                      self.name)
234        return None
235
236
237    def set_security_wpapsk(self, security, shared_key, update_interval=1800):
238        """Enabled WPA using a private security key for the wireless network.
239
240        Note: The derived class must implement this method.
241
242        @param security: Required security for AP configuration
243        @param shared_key: shared encryption key to use
244        @param update_interval: number of seconds to wait before updating
245
246        """
247        self.add_item_to_command_list(self._set_security_wpapsk,
248                                      (security, shared_key, update_interval),
249                                       1, 900)
250
251
252    def _set_security_wpapsk(self, security, shared_key, update_interval=1800):
253        if security == ap_spec.SECURITY_TYPE_WPAPSK:
254            self.select_item_from_popup_by_id('WPA-PSK', 'AuthMenu')
255        if security == ap_spec.SECURITY_TYPE_WPA2PSK:
256            self.select_item_from_popup_by_id('WPA2-PSK', 'AuthMenu')
257        self.select_item_from_popup_by_id('AUTO', 'Cipher',
258             wait_for_xpath='id("GKUI")')
259        if update_interval in range(300, 9999999):
260            self.set_content_of_text_field_by_id(str(update_interval),
261                                             'GKUI')
262        else:
263            raise RuntimeError('Update interval is %, not within range',
264                               update_interval)
265        self.set_content_of_text_field_by_id(shared_key,
266                                             'PassPhrase')
267
268
269    def set_visibility(self, visible=True):
270        """Set the visibility of the wireless network.
271
272        Note: The derived class must implement this method.
273
274        @param visible: True for visible; False otherwise
275
276        """
277        self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900)
278
279
280    def _set_visibility(self, visible=True):
281        found_id = self.wait_for_objects_by_id(['SsidBroadcast'],
282                                               wait_time=30)
283        if ('SsidBroadcast' in found_id) and visible:
284            self.select_item_from_popup_by_id('Enable', 'SsidBroadcast')
285        else:
286            self.select_item_from_popup_by_id('Disable', 'SsidBroadcast')
287