• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2019 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import itertools
18
19from acts import asserts
20from acts import utils
21from acts.controllers.access_point import setup_ap
22from acts.controllers.ap_lib import hostapd_constants
23from acts.controllers.ap_lib import hostapd_config
24from acts.controllers.ap_lib.hostapd_security import Security
25from acts.controllers.ap_lib.hostapd_utils import generate_random_password
26from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device
27from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
28
29FREQUENCY_24 = ['2.4GHz']
30FREQUENCY_5 = ['5GHz']
31CHANNEL_BANDWIDTH_20 = ['HT20']
32CHANNEL_BANDWIDTH_40_LOWER = ['HT40-']
33CHANNEL_BANDWIDTH_40_UPPER = ['HT40+']
34SECURITY_OPEN = 'open'
35SECURITY_WPA2 = 'wpa2'
36N_MODE = [hostapd_constants.MODE_11N_PURE, hostapd_constants.MODE_11N_MIXED]
37LDPC = [hostapd_constants.N_CAPABILITY_LDPC, '']
38TX_STBC = [hostapd_constants.N_CAPABILITY_TX_STBC, '']
39RX_STBC = [hostapd_constants.N_CAPABILITY_RX_STBC1, '']
40SGI_20 = [hostapd_constants.N_CAPABILITY_SGI20, '']
41SGI_40 = [hostapd_constants.N_CAPABILITY_SGI40, '']
42DSSS_CCK = [hostapd_constants.N_CAPABILITY_DSSS_CCK_40, '']
43INTOLERANT_40 = [hostapd_constants.N_CAPABILITY_40_INTOLERANT, '']
44MAX_AMPDU_7935 = [hostapd_constants.N_CAPABILITY_MAX_AMSDU_7935, '']
45SMPS = [hostapd_constants.N_CAPABILITY_SMPS_STATIC, '']
46
47
48def generate_test_name(settings):
49    """Generates a string based on the n_capabilities for a test case
50
51    Args:
52        settings: A dictionary of hostapd constant n_capabilities.
53
54    Returns:
55        A string that represents a test case name.
56    """
57    ret = []
58    for cap in hostapd_constants.N_CAPABILITIES_MAPPING.keys():
59        if cap in settings['n_capabilities']:
60            ret.append(hostapd_constants.N_CAPABILITIES_MAPPING[cap])
61    # '+' is used by Mobile Harness as special character, don't use it in test names
62    if settings['chbw'] == 'HT40-':
63        chbw = "HT40Lower"
64    elif settings['chbw'] == 'HT40+':
65        chbw = "HT40Upper"
66    else:
67        chbw = settings['chbw']
68    return 'test_11n_%s_%s_%s_%s_%s' % (settings['frequency'], chbw,
69                                        settings['security'],
70                                        settings['n_mode'], ''.join(ret))
71
72
73class WlanPhyCompliance11NTest(WifiBaseTest):
74    """Tests for validating 11n PHYS.
75
76    Test Bed Requirement:
77    * One Android device or Fuchsia device
78    * One Access Point
79    """
80
81    def __init__(self, controllers):
82        super().__init__(controllers)
83
84    def setup_generated_tests(self):
85        test_args = self._generate_24_HT20_test_args() + \
86            self._generate_24_HT40_lower_test_args() + \
87            self._generate_24_HT40_upper_test_args() + \
88            self._generate_5_HT20_test_args() + \
89            self._generate_5_HT40_lower_test_args() + \
90            self._generate_5_HT40_upper_test_args() + \
91            self._generate_24_HT20_wpa2_test_args() + \
92            self._generate_24_HT40_lower_wpa2_test_args() + \
93            self._generate_24_HT40_upper_wpa2_test_args() + \
94            self._generate_5_HT20_wpa2_test_args() + \
95            self._generate_5_HT40_lower_wpa2_test_args() + \
96            self._generate_5_HT40_upper_wpa2_test_args()
97
98        self.generate_tests(test_logic=self.setup_and_connect,
99                            name_func=generate_test_name,
100                            arg_sets=test_args)
101
102    def setup_class(self):
103        super().setup_class()
104        if 'dut' in self.user_params:
105            if self.user_params['dut'] == 'fuchsia_devices':
106                self.dut = create_wlan_device(self.fuchsia_devices[0])
107            elif self.user_params['dut'] == 'android_devices':
108                self.dut = create_wlan_device(self.android_devices[0])
109            else:
110                raise ValueError('Invalid DUT specified in config. (%s)' %
111                                 self.user_params['dut'])
112        else:
113            # Default is an android device, just like the other tests
114            self.dut = create_wlan_device(self.android_devices[0])
115
116        self.access_point = self.access_points[0]
117        self.access_point.stop_all_aps()
118
119    def setup_test(self):
120        if hasattr(self, "android_devices"):
121            for ad in self.android_devices:
122                ad.droid.wakeLockAcquireBright()
123                ad.droid.wakeUpNow()
124        self.dut.wifi_toggle_state(True)
125
126    def teardown_test(self):
127        if hasattr(self, "android_devices"):
128            for ad in self.android_devices:
129                ad.droid.wakeLockRelease()
130                ad.droid.goToSleepNow()
131        self.dut.turn_location_off_and_scan_toggle_off()
132        self.dut.disconnect()
133        self.dut.reset_wifi()
134        self.download_ap_logs()
135        self.access_point.stop_all_aps()
136
137    def on_fail(self, test_name, begin_time):
138        super().on_fail(test_name, begin_time)
139        self.access_point.stop_all_aps()
140
141    def setup_and_connect(self, ap_settings):
142        """Generates a hostapd config, setups up the AP with that config, then
143           attempts to associate a DUT
144
145        Args:
146               ap_settings: A dictionary of hostapd constant n_capabilities.
147        """
148        ssid = utils.rand_ascii_str(20)
149        security_profile = None
150        password = None
151        temp_n_capabilities = list(ap_settings['n_capabilities'])
152        n_capabilities = []
153        for n_capability in temp_n_capabilities:
154            if n_capability in hostapd_constants.N_CAPABILITIES_MAPPING.keys():
155                n_capabilities.append(n_capability)
156
157        if ap_settings['chbw'] == 'HT20' or ap_settings['chbw'] == 'HT40+':
158            if ap_settings['frequency'] == '2.4GHz':
159                channel = 1
160            elif ap_settings['frequency'] == '5GHz':
161                channel = 36
162            else:
163                raise ValueError('Invalid frequence: %s' %
164                                 ap_settings['frequency'])
165
166        elif ap_settings['chbw'] == 'HT40-':
167            if ap_settings['frequency'] == '2.4GHz':
168                channel = 11
169            elif ap_settings['frequency'] == '5GHz':
170                channel = 60
171            else:
172                raise ValueError('Invalid frequency: %s' %
173                                 ap_settings['frequency'])
174
175        else:
176            raise ValueError('Invalid channel bandwidth: %s' %
177                             ap_settings['chbw'])
178
179        if ap_settings['chbw'] == 'HT40-' or ap_settings['chbw'] == 'HT40+':
180            if hostapd_config.ht40_plus_allowed(channel):
181                extended_channel = hostapd_constants.N_CAPABILITY_HT40_PLUS
182            elif hostapd_config.ht40_minus_allowed(channel):
183                extended_channel = hostapd_constants.N_CAPABILITY_HT40_MINUS
184            else:
185                raise ValueError('Invalid channel: %s' % channel)
186            n_capabilities.append(extended_channel)
187
188        if ap_settings['security'] == 'wpa2':
189            security_profile = Security(
190                security_mode=SECURITY_WPA2,
191                password=generate_random_password(length=20),
192                wpa_cipher='CCMP',
193                wpa2_cipher='CCMP')
194            password = security_profile.password
195        target_security = hostapd_constants.SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get(
196            ap_settings['security'], None)
197
198        mode = ap_settings['n_mode']
199        if mode not in N_MODE:
200            raise ValueError('Invalid n-mode: %s' % ap_settings['n-mode'])
201
202        setup_ap(access_point=self.access_point,
203                 profile_name='whirlwind',
204                 mode=mode,
205                 channel=channel,
206                 n_capabilities=n_capabilities,
207                 ac_capabilities=[],
208                 force_wmm=True,
209                 ssid=ssid,
210                 security=security_profile,
211                 password=password)
212        asserts.assert_true(
213            self.dut.associate(ssid,
214                               target_pwd=password,
215                               target_security=target_security),
216            'Failed to connect.')
217
218    def _generate_24_HT20_test_args(self):
219        test_args = []
220        for combination in itertools.product(FREQUENCY_24,
221                                             CHANNEL_BANDWIDTH_20, N_MODE,
222                                             LDPC, TX_STBC, RX_STBC, SGI_20,
223                                             INTOLERANT_40, MAX_AMPDU_7935,
224                                             SMPS):
225            test_frequency = combination[0]
226            test_chbw = combination[1]
227            n_mode = combination[2]
228            n_capabilities = combination[3:]
229            test_args.append(({
230                'frequency': test_frequency,
231                'chbw': test_chbw,
232                'n_mode': n_mode,
233                'security': SECURITY_OPEN,
234                'n_capabilities': n_capabilities,
235            }, ))
236        return test_args
237
238    def _generate_24_HT40_lower_test_args(self):
239        test_args = []
240        for combination in itertools.product(FREQUENCY_24,
241                                             CHANNEL_BANDWIDTH_40_LOWER, LDPC,
242                                             TX_STBC, RX_STBC, SGI_20, SGI_40,
243                                             MAX_AMPDU_7935, SMPS, DSSS_CCK):
244            test_frequency = combination[0]
245            test_chbw = combination[1]
246            n_capabilities = combination[2:]
247            test_args.append(({
248                'frequency': test_frequency,
249                'chbw': test_chbw,
250                'n_mode': hostapd_constants.MODE_11N_MIXED,
251                'security': SECURITY_OPEN,
252                'n_capabilities': n_capabilities
253            }, ))
254        return test_args
255
256    def _generate_24_HT40_upper_test_args(self):
257        test_args = []
258        for combination in itertools.product(FREQUENCY_24,
259                                             CHANNEL_BANDWIDTH_40_UPPER, LDPC,
260                                             TX_STBC, RX_STBC, SGI_20, SGI_40,
261                                             MAX_AMPDU_7935, SMPS, DSSS_CCK):
262            test_frequency = combination[0]
263            test_chbw = combination[1]
264            n_capabilities = combination[2:]
265            test_args.append(({
266                'frequency': test_frequency,
267                'chbw': test_chbw,
268                'n_mode': hostapd_constants.MODE_11N_MIXED,
269                'security': SECURITY_OPEN,
270                'n_capabilities': n_capabilities
271            }, ))
272        return test_args
273
274    def _generate_5_HT20_test_args(self):
275        test_args = []
276        for combination in itertools.product(FREQUENCY_5, CHANNEL_BANDWIDTH_20,
277                                             LDPC, TX_STBC, RX_STBC, SGI_20,
278                                             INTOLERANT_40, MAX_AMPDU_7935,
279                                             SMPS):
280            test_frequency = combination[0]
281            test_chbw = combination[1]
282            n_capabilities = combination[2:]
283            test_args.append(({
284                'frequency': test_frequency,
285                'chbw': test_chbw,
286                'n_mode': hostapd_constants.MODE_11N_MIXED,
287                'security': SECURITY_OPEN,
288                'n_capabilities': n_capabilities
289            }, ))
290        return test_args
291
292    def _generate_5_HT40_lower_test_args(self):
293        test_args = []
294        for combination in itertools.product(FREQUENCY_5,
295                                             CHANNEL_BANDWIDTH_40_LOWER, LDPC,
296                                             TX_STBC, RX_STBC, SGI_20, SGI_40,
297                                             MAX_AMPDU_7935, SMPS, DSSS_CCK):
298            test_frequency = combination[0]
299            test_chbw = combination[1]
300            n_capabilities = combination[2:]
301            test_args.append(({
302                'frequency': test_frequency,
303                'chbw': test_chbw,
304                'n_mode': hostapd_constants.MODE_11N_MIXED,
305                'security': SECURITY_OPEN,
306                'n_capabilities': n_capabilities
307            }, ))
308        return test_args
309
310    def _generate_5_HT40_upper_test_args(self):
311        test_args = []
312        for combination in itertools.product(FREQUENCY_5,
313                                             CHANNEL_BANDWIDTH_40_UPPER,
314                                             N_MODE, LDPC, TX_STBC, RX_STBC,
315                                             SGI_20, SGI_40, MAX_AMPDU_7935,
316                                             SMPS, DSSS_CCK):
317            test_frequency = combination[0]
318            test_chbw = combination[1]
319            n_mode = combination[2]
320            n_capabilities = combination[3:]
321            test_args.append(({
322                'frequency': test_frequency,
323                'chbw': test_chbw,
324                'n_mode': n_mode,
325                'security': SECURITY_OPEN,
326                'n_capabilities': n_capabilities
327            }, ))
328        return test_args
329
330    def _generate_24_HT20_wpa2_test_args(self):
331        test_args = []
332        for combination in itertools.product(FREQUENCY_24,
333                                             CHANNEL_BANDWIDTH_20, LDPC,
334                                             TX_STBC, RX_STBC, SGI_20,
335                                             INTOLERANT_40, MAX_AMPDU_7935,
336                                             SMPS):
337            test_frequency = combination[0]
338            test_chbw = combination[1]
339            n_capabilities = combination[2:]
340            test_args.append(({
341                'frequency': test_frequency,
342                'chbw': test_chbw,
343                'n_mode': hostapd_constants.MODE_11N_MIXED,
344                'security': SECURITY_WPA2,
345                'n_capabilities': n_capabilities
346            }, ))
347        return test_args
348
349    def _generate_24_HT40_lower_wpa2_test_args(self):
350        test_args = []
351        for combination in itertools.product(FREQUENCY_24,
352                                             CHANNEL_BANDWIDTH_40_LOWER, LDPC,
353                                             TX_STBC, RX_STBC, SGI_20, SGI_40,
354                                             MAX_AMPDU_7935, SMPS, DSSS_CCK):
355            test_frequency = combination[0]
356            test_chbw = combination[1]
357            n_capabilities = combination[2:]
358            test_args.append(({
359                'frequency': test_frequency,
360                'chbw': test_chbw,
361                'n_mode': hostapd_constants.MODE_11N_MIXED,
362                'security': SECURITY_WPA2,
363                'n_capabilities': n_capabilities
364            }, ))
365        return test_args
366
367    def _generate_24_HT40_upper_wpa2_test_args(self):
368        test_args = []
369        for combination in itertools.product(FREQUENCY_24,
370                                             CHANNEL_BANDWIDTH_40_UPPER, LDPC,
371                                             TX_STBC, RX_STBC, SGI_20, SGI_40,
372                                             MAX_AMPDU_7935, SMPS, DSSS_CCK):
373            test_frequency = combination[0]
374            test_chbw = combination[1]
375            n_capabilities = combination[2:]
376            test_args.append(({
377                'frequency': test_frequency,
378                'chbw': test_chbw,
379                'n_mode': hostapd_constants.MODE_11N_MIXED,
380                'security': SECURITY_WPA2,
381                'n_capabilities': n_capabilities
382            }, ))
383        return test_args
384
385    def _generate_5_HT20_wpa2_test_args(self):
386        test_args = []
387        for combination in itertools.product(FREQUENCY_5, CHANNEL_BANDWIDTH_20,
388                                             LDPC, TX_STBC, RX_STBC, SGI_20,
389                                             INTOLERANT_40, MAX_AMPDU_7935,
390                                             SMPS):
391            test_frequency = combination[0]
392            test_chbw = combination[1]
393            n_capabilities = combination[2:]
394            test_args.append(({
395                'frequency': test_frequency,
396                'chbw': test_chbw,
397                'n_mode': hostapd_constants.MODE_11N_MIXED,
398                'security': SECURITY_WPA2,
399                'n_capabilities': n_capabilities
400            }, ))
401        return test_args
402
403    def _generate_5_HT40_lower_wpa2_test_args(self):
404        test_args = []
405        for combination in itertools.product(FREQUENCY_5,
406                                             CHANNEL_BANDWIDTH_40_LOWER, LDPC,
407                                             TX_STBC, RX_STBC, SGI_20, SGI_40,
408                                             MAX_AMPDU_7935, SMPS, DSSS_CCK):
409            test_frequency = combination[0]
410            test_chbw = combination[1]
411            n_capabilities = combination[2:]
412            test_args.append(({
413                'frequency': test_frequency,
414                'chbw': test_chbw,
415                'n_mode': hostapd_constants.MODE_11N_MIXED,
416                'security': SECURITY_WPA2,
417                'n_capabilities': n_capabilities
418            }, ))
419        return test_args
420
421    def _generate_5_HT40_upper_wpa2_test_args(self):
422        test_args = []
423        for combination in itertools.product(FREQUENCY_5,
424                                             CHANNEL_BANDWIDTH_40_UPPER, LDPC,
425                                             TX_STBC, RX_STBC, SGI_20, SGI_40,
426                                             MAX_AMPDU_7935, SMPS, DSSS_CCK):
427            test_frequency = combination[0]
428            test_chbw = combination[1]
429            n_capabilities = combination[2:]
430            test_args.append(({
431                'frequency': test_frequency,
432                'chbw': test_chbw,
433                'n_mode': hostapd_constants.MODE_11N_MIXED,
434                'security': SECURITY_WPA2,
435                'n_capabilities': n_capabilities
436            }, ))
437        return test_args
438