1# Copyright (c) 2013 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 MediaLink wapr150n router."""
6
7import logging
8import urlparse
9
10import dynamic_ap_configurator
11import ap_spec
12
13
14class MediaLinkAPConfigurator(
15        dynamic_ap_configurator.DynamicAPConfigurator):
16    """Class to control MediaLink wapr150n router."""
17
18
19    def __init__(self, ap_config=None):
20        super(MediaLinkAPConfigurator, self).__init__(ap_config=ap_config)
21        self.current_mode = ap_spec.MODE_B
22        self.add_item_to_command_list(self._set_mode, (self.current_mode, ),
23                                      1, 500)
24
25
26    def _alert_handler(self, alert):
27        text = alert.text
28        if 'Please input 10 or 26 characters of wep key1 !' in text:
29            alert.accept()
30            raise RuntimeError('We got an alert. %s' % text)
31        elif 'turn on wireless' in text:
32            alert.accept()
33            raise RuntimeError('Please enable wireless. %s' % text)
34        elif 'Invalid Wep key1 format' in text:
35            alert.accept()
36            raise RuntimeError('WEP key should be numbers. %s' % text)
37        elif 'system error' in text:
38            alert.accept()
39            raise RuntimeError('There was a system error on AP!')
40        elif 'Successful' in text:
41            alert.accept()
42        else:
43            raise RuntimeError('We have an unhandled alert: %s' % text)
44
45
46    def get_number_of_pages(self):
47        return 2
48
49
50    def get_supported_bands(self):
51        return [{'band': ap_spec.BAND_2GHZ,
52                 'channels': ['AutoSelect', 1, 2, 3, 4, 5, 6, 7,
53                              8, 9, 10, 11, 12, 13]}]
54
55
56    def get_supported_modes(self):
57        return [{'band': ap_spec.BAND_2GHZ,
58                 'modes': [ap_spec.MODE_B, ap_spec.MODE_G, ap_spec.MODE_B |
59                           ap_spec.MODE_G, ap_spec.MODE_B | ap_spec.MODE_G |
60                           ap_spec.MODE_N]}]
61
62
63    def is_security_mode_supported(self, security_mode):
64        return security_mode in (ap_spec.SECURITY_TYPE_DISABLED,
65                                 ap_spec.SECURITY_TYPE_WPAPSK,
66                                 ap_spec.SECURITY_TYPE_WPA2PSK,
67                                 ap_spec.SECURITY_TYPE_WEP)
68
69
70    def navigate_to_page(self, page_number):
71        if page_number == 1:
72            url = urlparse.urljoin(self.admin_interface_url,
73                                   'wireless_basic.asp')
74            self.get_url(url, page_title='wireless_basic.asp')
75            self.wait_for_object_by_xpath('//input[@name="ssid"]')
76        elif page_number == 2:
77            url = urlparse.urljoin(self.admin_interface_url,
78                                   'wireless_security.asp')
79            self.get_url(url, page_title='wireless_security.asp')
80            self.wait_for_object_by_xpath('//select[@name="security_mode"]')
81        else:
82            raise RuntimeError('Invalid page number passed.  Number of pages '
83                               '%d, page value sent was %d' %
84                               (self.get_number_of_pages(), page_number))
85
86
87    def save_page(self, page_number):
88        xpath_apply = ('//input[@type="button" and @value="Apply"]')
89        self.click_button_by_xpath(xpath_apply,
90                                   alert_handler=self._alert_handler)
91        try:
92            self.wait_for_object_by_xpath('//input[@type="button" and '
93                                          '@value="OK"]')
94        except:
95            self._handle_alert(xpath_apply, self._alert_handler)
96
97
98    def is_update_interval_supported(self):
99        """
100        Returns True if setting the PSK refresh interval is supported.
101
102        @return True is supported; False otherwise
103        """
104        return True
105
106    def set_mode(self, mode, band=None):
107        self.add_item_to_command_list(self._set_mode, (mode, ), 1, 800)
108
109
110    def _set_mode(self, mode):
111        if mode == ap_spec.MODE_B:
112            mode_popup = '11b mode'
113        elif mode == ap_spec.MODE_G:
114            mode_popup = '11g mode'
115        elif mode == (ap_spec.MODE_B | ap_spec.MODE_G):
116            mode_popup = '11b/g mixed mode'
117        elif mode == (ap_spec.MODE_B | ap_spec.MODE_G | ap_spec.MODE_N):
118            mode_popup = '11b/g/n mixed mode'
119        else:
120            raise RuntimeError('Invalid mode passed: %x' % mode)
121        self.current_mode = mode
122        self._set_radio(enabled=True)
123        xpath = '//select[@name="wirelessmode"]'
124        self.select_item_from_popup_by_xpath(mode_popup, xpath)
125
126
127    def set_radio(self, enabled=True):
128        self.add_item_to_command_list(self._set_radio, (enabled, ), 1, 1000)
129
130
131    def _set_radio(self, enabled=True):
132        xpath = '//input[@name="enablewireless" and @type="checkbox"]'
133        self.set_check_box_selected_by_xpath(xpath, selected=enabled,
134                                             wait_for_xpath=None,
135                                             alert_handler=self._alert_handler)
136
137
138    def set_ssid(self, ssid):
139        self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)
140
141
142    def _set_ssid(self, ssid):
143        self._set_radio(enabled=True)
144        xpath = '//input[@name="ssid"]'
145        self.set_content_of_text_field_by_xpath(ssid, xpath)
146        self._ssid = ssid
147
148
149    def set_channel(self, channel):
150        self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)
151
152
153    def _set_channel(self, channel):
154        position = self._get_channel_popup_position(channel)
155        self._set_radio(enabled=True)
156        channel_choices = ['AutoSelect', '2412MHz (Channel 1)',
157                           '2417MHz (Channel 2)', '2422MHz (Channel 3)',
158                           '2427MHz (Channel 4)', '2432MHz (Channel 5)',
159                           '2437MHz (Channel 6)', '2442MHz (Channel 7)',
160                           '2447MHz (Channel 8)', '2452MHz (Channel 9)',
161                           '2457MHz (Channel 10)', '2462MHz (Channel 11)',
162                           '2467MHz (Channel 12)', '2472MHz (Channel 13)']
163        if self.current_mode == ap_spec.MODE_B:
164            xpath = '//select[@name="sz11bChannel"]'
165        else:
166            xpath = '//select[@name="sz11gChannel"]'
167        self.select_item_from_popup_by_xpath(channel_choices[position], xpath,
168                                             alert_handler=self._alert_handler)
169
170
171    def set_band(self, band):
172        logging.debug('This router %s does not support multiple bands.',
173                      self.name)
174        return None
175
176
177    def set_security_disabled(self):
178        self.add_item_to_command_list(self._set_security_disabled, (), 2, 900)
179
180
181    def _set_security_disabled(self):
182        xpath = '//select[@name="security_mode"]'
183        self.select_item_from_popup_by_xpath('Disable', xpath)
184
185
186    def set_security_wep(self, key_value, authentication):
187        self.add_item_to_command_list(self._set_security_wep,
188                                      (key_value, authentication), 2, 900)
189
190
191    def _set_security_wep(self, key_value, authentication):
192        logging.debug('This router %s does not support WEP authentication type:'
193                      ' %s', self.name, authentication)
194        popup = '//select[@name="security_mode"]'
195        text_field = '//input[@name="wep_key_1"]'
196        self.select_item_from_popup_by_xpath('Mixed WEP', popup,
197                                             wait_for_xpath=text_field)
198        self.set_content_of_text_field_by_xpath(key_value, text_field,
199                                                abort_check=True)
200
201
202    def set_security_wpapsk(self, security, shared_key, update_interval=1800):
203        self.add_item_to_command_list(self._set_security_wpapsk,
204                                      (security, shared_key,update_interval,),
205                                       2, 900)
206
207
208    def _set_security_wpapsk(self, security, shared_key, update_interval=1800):
209        if update_interval < 600 | update_interval > 7200:
210            logging.debug('Invalid update interval, setting it to 1800.')
211            update_interval = 1800
212        popup = '//select[@name="security_mode"]'
213        key_field = '//input[@name="passphrase"]'
214        if security == ap_spec.SECURITY_TYPE_WPAPSK:
215            wpa_item = 'WPA - Personal'
216        else:
217            wpa_item = 'WPA2 - Personal'
218        self.select_item_from_popup_by_xpath(wpa_item, popup,
219                                             wait_for_xpath=key_field)
220        self.set_content_of_text_field_by_xpath(shared_key, key_field,
221                                                abort_check=True)
222        interval_field = ('//input[@name="keyRenewalInterval"]')
223        self.set_content_of_text_field_by_xpath(str(update_interval),
224                                                interval_field)
225
226
227    def set_visibility(self, visible=True):
228        self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900)
229
230
231    def _set_visibility(self, visible=True):
232        self._set_radio(enabled=True)
233        int_value = int(visible)
234        xpath = '//input[@name="broadcastssid" and @value="%d"]' % int_value
235        self.click_button_by_xpath(xpath)
236