blob: 897868f69864bcded64e3f26e81c200f73c258d3 [file] [log] [blame]
Mark De Ruyter1a7ae572018-03-02 15:35:36 -08001#!/usr/bin/env python3
Joe Brennan8c24a812017-04-13 14:27:05 -07002#
3# Copyright 2017 - Google
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.
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +000016"""
17 Base Class for Defining Common WiFi Test Functionality
18"""
Joe Brennan8c24a812017-04-13 14:27:05 -070019
Bindu Mahadev1f227e02017-07-06 00:24:58 +000020import copy
21import itertools
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +080022import os
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +000023import time
24
25import acts.controllers.access_point as ap
Bindu Mahadevedf17162017-07-07 03:46:55 +000026
Joe Brennan8c24a812017-04-13 14:27:05 -070027from acts import asserts
Girish Moturue6ccc7a2019-09-19 11:00:21 -070028from acts import signals
Joe Brennan8c24a812017-04-13 14:27:05 -070029from acts import utils
30from acts.base_test import BaseTestClass
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +000031from acts.signals import TestSignal
32from acts.controllers import android_device
Girish Moturu27ff0b32019-08-03 21:44:59 -070033from acts.controllers.access_point import AccessPoint
Joe Brennan8c24a812017-04-13 14:27:05 -070034from acts.controllers.ap_lib import hostapd_ap_preset
35from acts.controllers.ap_lib import hostapd_bss_settings
36from acts.controllers.ap_lib import hostapd_constants
37from acts.controllers.ap_lib import hostapd_security
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +080038from acts.keys import Config
Xianyuan Jia63751fb2020-11-17 00:07:40 +000039from acts_contrib.test_utils.net import net_test_utils as nutils
40from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
Joe Brennan8c24a812017-04-13 14:27:05 -070041
Bindu Mahadeve7d47c32018-07-03 16:48:03 -070042AP_1 = 0
43AP_2 = 1
44MAX_AP_COUNT = 2
Joe Brennan8c24a812017-04-13 14:27:05 -070045
Nate Jiang8bbc94f2019-06-11 19:13:51 -070046
Joe Brennan8c24a812017-04-13 14:27:05 -070047class WifiBaseTest(BaseTestClass):
Hsiu-Chang Chen20ad5a12020-10-30 11:31:56 +080048
49 def __init__(self, configs):
50 super().__init__(configs)
51 self.enable_packet_log = False
52 self.packet_log_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G
53 self.packet_log_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G
54
Xianyuan Jia168103b2019-09-06 12:22:52 -070055 def setup_class(self):
Bindu Mahadevd3eaf5d2018-05-08 15:32:26 -070056 if hasattr(self, 'attenuators') and self.attenuators:
Bindu Mahadev3bb29fa2017-08-10 16:08:20 +000057 for attenuator in self.attenuators:
58 attenuator.set_atten(0)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +080059 opt_param = ["pixel_models", "cnss_diag_file"]
60 self.unpack_userparams(opt_param_names=opt_param)
61 if hasattr(self, "cnss_diag_file"):
62 if isinstance(self.cnss_diag_file, list):
63 self.cnss_diag_file = self.cnss_diag_file[0]
64 if not os.path.isfile(self.cnss_diag_file):
65 self.cnss_diag_file = os.path.join(
66 self.user_params[Config.key_config_path.value],
67 self.cnss_diag_file)
Hsiu-Chang Chen20ad5a12020-10-30 11:31:56 +080068 if self.enable_packet_log and hasattr(self, "packet_capture"):
69 self.packet_logger = self.packet_capture[0]
70 self.packet_logger.configure_monitor_mode("2G", self.packet_log_2g)
71 self.packet_logger.configure_monitor_mode("5G", self.packet_log_5g)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +080072
73 def setup_test(self):
74 if (hasattr(self, "android_devices") and
75 hasattr(self, "cnss_diag_file") and
76 hasattr(self, "pixel_models")):
77 wutils.start_cnss_diags(
78 self.android_devices, self.cnss_diag_file, self.pixel_models)
Hsiu-Chang Chenfb04a552020-10-21 10:40:12 +080079 self.tcpdump_proc = []
80 if hasattr(self, "android_devices"):
81 for ad in self.android_devices:
82 proc = nutils.start_tcpdump(ad, self.test_name)
83 self.tcpdump_proc.append((ad, proc))
Hsiu-Chang Chen20ad5a12020-10-30 11:31:56 +080084 if hasattr(self, "packet_logger"):
85 self.packet_log_pid = wutils.start_pcap(
86 self.packet_logger, 'dual', self.test_name)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +080087
88 def teardown_test(self):
89 if (hasattr(self, "android_devices") and
90 hasattr(self, "cnss_diag_file") and
91 hasattr(self, "pixel_models")):
92 wutils.stop_cnss_diags(self.android_devices, self.pixel_models)
Hsiu-Chang Chenfb04a552020-10-21 10:40:12 +080093 for proc in self.tcpdump_proc:
94 nutils.stop_tcpdump(
95 proc[0], proc[1], self.test_name, pull_dump=False)
96 self.tcpdump_proc = []
Hsiu-Chang Chen20ad5a12020-10-30 11:31:56 +080097 if hasattr(self, "packet_logger") and self.packet_log_pid:
98 wutils.stop_pcap(
99 self.packet_logger, self.packet_log_pid, test_status=True)
100 self.packet_log_pid = {}
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +0800101
102 def on_fail(self, test_name, begin_time):
103 if hasattr(self, "android_devices"):
104 for ad in self.android_devices:
105 ad.take_bug_report(test_name, begin_time)
106 ad.cat_adb_log(test_name, begin_time)
107 wutils.get_ssrdumps(ad)
108 if (hasattr(self, "cnss_diag_file") and
109 hasattr(self, "pixel_models")):
110 wutils.stop_cnss_diags(self.android_devices, self.pixel_models)
111 for ad in self.android_devices:
112 wutils.get_cnss_diag_log(ad)
Hsiu-Chang Chenfb04a552020-10-21 10:40:12 +0800113 for proc in self.tcpdump_proc:
114 nutils.stop_tcpdump(proc[0], proc[1], self.test_name)
115 self.tcpdump_proc = []
Hsiu-Chang Chen20ad5a12020-10-30 11:31:56 +0800116 if hasattr(self, "packet_logger") and self.packet_log_pid:
117 wutils.stop_pcap(
118 self.packet_logger, self.packet_log_pid, test_status=False)
119 self.packet_log_pid = {}
Joe Brennan8c24a812017-04-13 14:27:05 -0700120
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800121 def get_psk_network(
Bindu Mahadev72725d12017-06-05 03:11:30 +0000122 self,
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700123 mirror_ap,
124 reference_networks,
Bindu Mahadev1c895c22018-01-18 18:20:43 -0800125 hidden=False,
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700126 same_ssid=False,
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800127 security_mode=hostapd_constants.WPA2_STRING,
Bindu Mahadev72725d12017-06-05 03:11:30 +0000128 ssid_length_2g=hostapd_constants.AP_SSID_LENGTH_2G,
129 ssid_length_5g=hostapd_constants.AP_SSID_LENGTH_5G,
130 passphrase_length_2g=hostapd_constants.AP_PASSPHRASE_LENGTH_2G,
131 passphrase_length_5g=hostapd_constants.AP_PASSPHRASE_LENGTH_5G):
Bindu Mahadev72725d12017-06-05 03:11:30 +0000132 """Generates SSID and passphrase for a WPA2 network using random
133 generator.
134
135 Args:
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700136 mirror_ap: Boolean, determines if both APs use the same hostapd
137 config or different configs.
138 reference_networks: List of PSK networks.
139 same_ssid: Boolean, determines if both bands on AP use the same
140 SSID.
141 ssid_length_2gecond AP Int, number of characters to use for 2G SSID.
Bindu Mahadev72725d12017-06-05 03:11:30 +0000142 ssid_length_5g: Int, number of characters to use for 5G SSID.
143 passphrase_length_2g: Int, length of password for 2G network.
144 passphrase_length_5g: Int, length of password for 5G network.
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700145
Bindu Mahadev72725d12017-06-05 03:11:30 +0000146 Returns: A dict of 2G and 5G network lists for hostapd configuration.
147
148 """
149 network_dict_2g = {}
150 network_dict_5g = {}
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800151 ref_5g_security = security_mode
152 ref_2g_security = security_mode
Bindu Mahadev72725d12017-06-05 03:11:30 +0000153
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700154 if same_ssid:
155 ref_2g_ssid = 'xg_%s' % utils.rand_ascii_str(ssid_length_2g)
156 ref_5g_ssid = ref_2g_ssid
Bindu Mahadev72725d12017-06-05 03:11:30 +0000157
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700158 ref_2g_passphrase = utils.rand_ascii_str(passphrase_length_2g)
159 ref_5g_passphrase = ref_2g_passphrase
160
161 else:
162 ref_2g_ssid = '2g_%s' % utils.rand_ascii_str(ssid_length_2g)
163 ref_2g_passphrase = utils.rand_ascii_str(passphrase_length_2g)
164
165 ref_5g_ssid = '5g_%s' % utils.rand_ascii_str(ssid_length_5g)
166 ref_5g_passphrase = utils.rand_ascii_str(passphrase_length_5g)
Bindu Mahadev72725d12017-06-05 03:11:30 +0000167
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800168 network_dict_2g = {
169 "SSID": ref_2g_ssid,
170 "security": ref_2g_security,
171 "password": ref_2g_passphrase,
172 "hiddenSSID": hidden
173 }
Bindu Mahadev72725d12017-06-05 03:11:30 +0000174
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800175 network_dict_5g = {
176 "SSID": ref_5g_ssid,
177 "security": ref_5g_security,
178 "password": ref_5g_passphrase,
179 "hiddenSSID": hidden
180 }
Bindu Mahadev1c895c22018-01-18 18:20:43 -0800181
Bindu Mahadevd07198d2017-09-15 14:06:54 -0700182 ap = 0
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700183 for ap in range(MAX_AP_COUNT):
184 reference_networks.append({
185 "2g": copy.copy(network_dict_2g),
186 "5g": copy.copy(network_dict_5g)
Bindu Mahadev72725d12017-06-05 03:11:30 +0000187 })
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700188 if not mirror_ap:
189 break
Bindu Mahadev72725d12017-06-05 03:11:30 +0000190 return {"2g": network_dict_2g, "5g": network_dict_5g}
191
markdr56939012017-07-26 12:48:43 -0700192 def get_open_network(self,
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700193 mirror_ap,
194 open_network,
Bindu Mahadev1c895c22018-01-18 18:20:43 -0800195 hidden=False,
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700196 same_ssid=False,
markdr56939012017-07-26 12:48:43 -0700197 ssid_length_2g=hostapd_constants.AP_SSID_LENGTH_2G,
Girish Moturu4bf0b932020-09-25 11:17:22 -0700198 ssid_length_5g=hostapd_constants.AP_SSID_LENGTH_5G,
199 security_mode='none'):
Bindu Mahadev72725d12017-06-05 03:11:30 +0000200 """Generates SSIDs for a open network using a random generator.
201
202 Args:
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700203 mirror_ap: Boolean, determines if both APs use the same hostapd
204 config or different configs.
205 open_network: List of open networks.
206 same_ssid: Boolean, determines if both bands on AP use the same
207 SSID.
Bindu Mahadev72725d12017-06-05 03:11:30 +0000208 ssid_length_2g: Int, number of characters to use for 2G SSID.
209 ssid_length_5g: Int, number of characters to use for 5G SSID.
Girish Moturu4bf0b932020-09-25 11:17:22 -0700210 security_mode: 'none' for open and 'OWE' for WPA3 OWE.
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700211
Bindu Mahadev72725d12017-06-05 03:11:30 +0000212 Returns: A dict of 2G and 5G network lists for hostapd configuration.
213
214 """
215 network_dict_2g = {}
216 network_dict_5g = {}
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700217
218 if same_ssid:
219 open_2g_ssid = 'xg_%s' % utils.rand_ascii_str(ssid_length_2g)
220 open_5g_ssid = open_2g_ssid
221
222 else:
223 open_2g_ssid = '2g_%s' % utils.rand_ascii_str(ssid_length_2g)
224 open_5g_ssid = '5g_%s' % utils.rand_ascii_str(ssid_length_5g)
225
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800226 network_dict_2g = {
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +0000227 "SSID": open_2g_ssid,
Girish Moturu4bf0b932020-09-25 11:17:22 -0700228 "security": security_mode,
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800229 "hiddenSSID": hidden
230 }
Bindu Mahadev1c895c22018-01-18 18:20:43 -0800231
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800232 network_dict_5g = {
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +0000233 "SSID": open_5g_ssid,
Girish Moturu4bf0b932020-09-25 11:17:22 -0700234 "security": security_mode,
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800235 "hiddenSSID": hidden
236 }
Bindu Mahadev1c895c22018-01-18 18:20:43 -0800237
Bindu Mahadevd07198d2017-09-15 14:06:54 -0700238 ap = 0
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700239 for ap in range(MAX_AP_COUNT):
240 open_network.append({
241 "2g": copy.copy(network_dict_2g),
242 "5g": copy.copy(network_dict_5g)
Bindu Mahadev72725d12017-06-05 03:11:30 +0000243 })
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700244 if not mirror_ap:
245 break
Bindu Mahadev72725d12017-06-05 03:11:30 +0000246 return {"2g": network_dict_2g, "5g": network_dict_5g}
247
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800248 def get_wep_network(
249 self,
250 mirror_ap,
251 networks,
252 hidden=False,
253 same_ssid=False,
254 ssid_length_2g=hostapd_constants.AP_SSID_LENGTH_2G,
255 ssid_length_5g=hostapd_constants.AP_SSID_LENGTH_5G,
256 passphrase_length_2g=hostapd_constants.AP_PASSPHRASE_LENGTH_2G,
257 passphrase_length_5g=hostapd_constants.AP_PASSPHRASE_LENGTH_5G):
258 """Generates SSID and passphrase for a WEP network using random
259 generator.
260
261 Args:
262 mirror_ap: Boolean, determines if both APs use the same hostapd
263 config or different configs.
264 networks: List of WEP networks.
265 same_ssid: Boolean, determines if both bands on AP use the same
266 SSID.
267 ssid_length_2gecond AP Int, number of characters to use for 2G SSID.
268 ssid_length_5g: Int, number of characters to use for 5G SSID.
269 passphrase_length_2g: Int, length of password for 2G network.
270 passphrase_length_5g: Int, length of password for 5G network.
271
272 Returns: A dict of 2G and 5G network lists for hostapd configuration.
273
274 """
275 network_dict_2g = {}
276 network_dict_5g = {}
277 ref_5g_security = hostapd_constants.WEP_STRING
278 ref_2g_security = hostapd_constants.WEP_STRING
279
280 if same_ssid:
281 ref_2g_ssid = 'xg_%s' % utils.rand_ascii_str(ssid_length_2g)
282 ref_5g_ssid = ref_2g_ssid
283
284 ref_2g_passphrase = utils.rand_hex_str(passphrase_length_2g)
285 ref_5g_passphrase = ref_2g_passphrase
286
287 else:
288 ref_2g_ssid = '2g_%s' % utils.rand_ascii_str(ssid_length_2g)
289 ref_2g_passphrase = utils.rand_hex_str(passphrase_length_2g)
290
291 ref_5g_ssid = '5g_%s' % utils.rand_ascii_str(ssid_length_5g)
292 ref_5g_passphrase = utils.rand_hex_str(passphrase_length_5g)
293
294 network_dict_2g = {
295 "SSID": ref_2g_ssid,
296 "security": ref_2g_security,
297 "wepKeys": [ref_2g_passphrase] * 4,
298 "hiddenSSID": hidden
299 }
300
301 network_dict_5g = {
302 "SSID": ref_5g_ssid,
303 "security": ref_5g_security,
304 "wepKeys": [ref_2g_passphrase] * 4,
305 "hiddenSSID": hidden
306 }
307
308 ap = 0
309 for ap in range(MAX_AP_COUNT):
310 networks.append({
311 "2g": copy.copy(network_dict_2g),
312 "5g": copy.copy(network_dict_5g)
313 })
314 if not mirror_ap:
315 break
316 return {"2g": network_dict_2g, "5g": network_dict_5g}
317
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700318 def update_bssid(self, ap_instance, ap, network, band):
319 """Get bssid and update network dictionary.
320
321 Args:
322 ap_instance: Accesspoint index that was configured.
323 ap: Accesspoint object corresponding to ap_instance.
324 network: Network dictionary.
325 band: Wifi networks' band.
326
327 """
328 bssid = ap.get_bssid_from_ssid(network["SSID"], band)
329
330 if network["security"] == hostapd_constants.WPA2_STRING:
331 # TODO:(bamahadev) Change all occurances of reference_networks
332 # to wpa_networks.
333 self.reference_networks[ap_instance][band]["bssid"] = bssid
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800334 if network["security"] == hostapd_constants.WPA_STRING:
335 self.wpa_networks[ap_instance][band]["bssid"] = bssid
336 if network["security"] == hostapd_constants.WEP_STRING:
337 self.wep_networks[ap_instance][band]["bssid"] = bssid
Girish Moturudcd73f62018-10-18 09:49:32 -0700338 if network["security"] == hostapd_constants.ENT_STRING:
Girish Moturuf1ce4202018-10-20 21:33:00 -0700339 if "bssid" not in self.ent_networks[ap_instance][band]:
340 self.ent_networks[ap_instance][band]["bssid"] = bssid
341 else:
342 self.ent_networks_pwd[ap_instance][band]["bssid"] = bssid
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700343 if network["security"] == 'none':
344 self.open_network[ap_instance][band]["bssid"] = bssid
345
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +0000346 def populate_bssid(self, ap_instance, ap, networks_5g, networks_2g):
Bindu Mahadev1f227e02017-07-06 00:24:58 +0000347 """Get bssid for a given SSID and add it to the network dictionary.
348
349 Args:
Bindu Mahadevd07198d2017-09-15 14:06:54 -0700350 ap_instance: Accesspoint index that was configured.
351 ap: Accesspoint object corresponding to ap_instance.
Mark De Ruyterdee24c22018-04-13 17:34:44 -0700352 networks_5g: List of 5g networks configured on the APs.
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +0000353 networks_2g: List of 2g networks configured on the APs.
Bindu Mahadev1f227e02017-07-06 00:24:58 +0000354
355 """
356
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +0000357 if not (networks_5g or networks_2g):
Bindu Mahadev1f227e02017-07-06 00:24:58 +0000358 return
359
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700360 for network in networks_5g:
Bindu Mahadev1f227e02017-07-06 00:24:58 +0000361 if 'channel' in network:
362 continue
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700363 self.update_bssid(ap_instance, ap, network,
364 hostapd_constants.BAND_5G)
365
366 for network in networks_2g:
367 if 'channel' in network:
368 continue
369 self.update_bssid(ap_instance, ap, network,
370 hostapd_constants.BAND_2G)
Bindu Mahadev1f227e02017-07-06 00:24:58 +0000371
Girish Moturuf17b5112020-07-17 09:30:00 -0700372 def configure_openwrt_ap_and_start(
373 self,
374 channel_5g=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
375 channel_2g=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
376 ssid_length_2g=hostapd_constants.AP_SSID_LENGTH_2G,
377 passphrase_length_2g=hostapd_constants.AP_PASSPHRASE_LENGTH_2G,
378 ssid_length_5g=hostapd_constants.AP_SSID_LENGTH_5G,
379 passphrase_length_5g=hostapd_constants.AP_PASSPHRASE_LENGTH_5G,
380 mirror_ap=False,
381 hidden=False,
382 same_ssid=False,
383 open_network=False,
384 wpa_network=False,
385 wep_network=False,
386 ent_network=False,
387 ent_network_pwd=False,
Girish Moturu4bf0b932020-09-25 11:17:22 -0700388 owe_network=False,
389 sae_network=False,
Girish Moturuf17b5112020-07-17 09:30:00 -0700390 radius_conf_2g=None,
391 radius_conf_5g=None,
392 radius_conf_pwd=None,
393 ap_count=1):
394 """Create, configure and start OpenWrt AP.
395
396 Args:
397 channel_5g: 5G channel to configure.
398 channel_2g: 2G channel to configure.
399 ssid_length_2g: Int, number of characters to use for 2G SSID.
400 passphrase_length_2g: Int, length of password for 2G network.
401 ssid_length_5g: Int, number of characters to use for 5G SSID.
402 passphrase_length_5g: Int, length of password for 5G network.
403 same_ssid: Boolean, determines if both bands on AP use the same SSID.
404 open_network: Boolean, to check if open network should be configured.
405 wpa_network: Boolean, to check if wpa network should be configured.
406 wep_network: Boolean, to check if wep network should be configured.
407 ent_network: Boolean, to check if ent network should be configured.
408 ent_network_pwd: Boolean, to check if ent pwd network should be configured.
Girish Moturu4bf0b932020-09-25 11:17:22 -0700409 owe_network: Boolean, to check if owe network should be configured.
410 sae_network: Boolean, to check if sae network should be configured.
Girish Moturuf17b5112020-07-17 09:30:00 -0700411 radius_conf_2g: dictionary with enterprise radius server details.
412 radius_conf_5g: dictionary with enterprise radius server details.
413 radius_conf_pwd: dictionary with enterprise radiuse server details.
414 ap_count: APs to configure.
415 """
Girish Moturu8ff7d972020-09-18 22:53:46 -0700416 if mirror_ap and ap_count == 1:
417 raise ValueError("ap_count cannot be 1 if mirror_ap is True.")
418
Girish Moturuf17b5112020-07-17 09:30:00 -0700419 self.reference_networks = []
420 self.wpa_networks = []
421 self.wep_networks = []
422 self.ent_networks = []
423 self.ent_networks_pwd = []
424 self.open_network = []
Girish Moturu4bf0b932020-09-25 11:17:22 -0700425 self.owe_networks = []
426 self.sae_networks = []
Girish Moturu8ff7d972020-09-18 22:53:46 -0700427 self.bssid_map = []
428 for i in range(ap_count):
Girish Moturuf17b5112020-07-17 09:30:00 -0700429 network_list = []
430 if wpa_network:
431 wpa_dict = self.get_psk_network(mirror_ap,
432 self.reference_networks,
433 hidden,
434 same_ssid,
435 ssid_length_2g,
436 ssid_length_5g,
437 passphrase_length_2g,
438 passphrase_length_5g)
439 wpa_dict[hostapd_constants.BAND_2G]["security"] = "psk2"
440 wpa_dict[hostapd_constants.BAND_5G]["security"] = "psk2"
441 self.wpa_networks.append(wpa_dict)
442 network_list.append(wpa_dict)
443 if wep_network:
444 wep_dict = self.get_wep_network(mirror_ap,
445 self.wep_networks,
446 hidden,
447 same_ssid,
448 ssid_length_2g,
449 ssid_length_5g)
450 network_list.append(wep_dict)
451 if ent_network:
452 ent_dict = self.get_open_network(mirror_ap,
453 self.ent_networks,
454 hidden,
455 same_ssid,
456 ssid_length_2g,
457 ssid_length_5g)
458 ent_dict["2g"]["security"] = "wpa2"
459 ent_dict["2g"].update(radius_conf_2g)
460 ent_dict["5g"]["security"] = "wpa2"
461 ent_dict["5g"].update(radius_conf_5g)
462 network_list.append(ent_dict)
463 if ent_network_pwd:
464 ent_pwd_dict = self.get_open_network(mirror_ap,
465 self.ent_networks_pwd,
466 hidden,
467 same_ssid,
468 ssid_length_2g,
469 ssid_length_5g)
470 ent_pwd_dict["2g"]["security"] = "wpa2"
471 ent_pwd_dict["2g"].update(radius_conf_pwd)
472 ent_pwd_dict["5g"]["security"] = "wpa2"
473 ent_pwd_dict["5g"].update(radius_conf_pwd)
474 network_list.append(ent_pwd_dict)
475 if open_network:
476 open_dict = self.get_open_network(mirror_ap,
477 self.open_network,
478 hidden,
479 same_ssid,
480 ssid_length_2g,
481 ssid_length_5g)
482 network_list.append(open_dict)
Girish Moturu4bf0b932020-09-25 11:17:22 -0700483 if owe_network:
484 owe_dict = self.get_open_network(mirror_ap,
485 self.owe_networks,
486 hidden,
487 same_ssid,
488 ssid_length_2g,
489 ssid_length_5g,
490 "OWE")
491 owe_dict[hostapd_constants.BAND_2G]["security"] = "owe"
492 owe_dict[hostapd_constants.BAND_5G]["security"] = "owe"
493 network_list.append(owe_dict)
494 if sae_network:
495 sae_dict = self.get_psk_network(mirror_ap,
496 self.sae_networks,
497 hidden,
498 same_ssid,
499 hostapd_constants.WPA3_KEY_MGMT,
500 ssid_length_2g,
501 ssid_length_5g,
502 passphrase_length_2g,
503 passphrase_length_5g)
504 sae_dict[hostapd_constants.BAND_2G]["security"] = "sae"
505 sae_dict[hostapd_constants.BAND_5G]["security"] = "sae"
506 network_list.append(sae_dict)
Girish Moturu8ff7d972020-09-18 22:53:46 -0700507 self.access_points[i].configure_ap(network_list,
Girish Moturuf17b5112020-07-17 09:30:00 -0700508 channel_2g,
509 channel_5g)
Girish Moturu8ff7d972020-09-18 22:53:46 -0700510 self.access_points[i].start_ap()
511 self.bssid_map.append(
512 self.access_points[i].get_bssids_for_wifi_networks())
513 if mirror_ap:
Girish Moturuf197bb72020-10-14 12:30:59 -0700514 self.access_points[i+1].configure_ap(network_list,
515 channel_2g,
516 channel_5g)
517 self.access_points[i+1].start_ap()
518 self.bssid_map.append(
519 self.access_points[i+1].get_bssids_for_wifi_networks())
520 break
Girish Moturuf17b5112020-07-17 09:30:00 -0700521
Joe Brennan8c24a812017-04-13 14:27:05 -0700522 def legacy_configure_ap_and_start(
523 self,
Mark De Ruyterdee24c22018-04-13 17:34:44 -0700524 channel_5g=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +0000525 channel_2g=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
526 max_2g_networks=hostapd_constants.AP_DEFAULT_MAX_SSIDS_2G,
527 max_5g_networks=hostapd_constants.AP_DEFAULT_MAX_SSIDS_5G,
528 ap_ssid_length_2g=hostapd_constants.AP_SSID_LENGTH_2G,
529 ap_passphrase_length_2g=hostapd_constants.AP_PASSPHRASE_LENGTH_2G,
530 ap_ssid_length_5g=hostapd_constants.AP_SSID_LENGTH_5G,
531 ap_passphrase_length_5g=hostapd_constants.AP_PASSPHRASE_LENGTH_5G,
532 hidden=False,
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700533 same_ssid=False,
534 mirror_ap=True,
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800535 wpa_network=False,
536 wep_network=False,
Girish Moturudcd73f62018-10-18 09:49:32 -0700537 ent_network=False,
538 radius_conf_2g=None,
539 radius_conf_5g=None,
Girish Moturuf1ce4202018-10-20 21:33:00 -0700540 ent_network_pwd=False,
541 radius_conf_pwd=None,
Bindu Mahadev72725d12017-06-05 03:11:30 +0000542 ap_count=1):
Joe Brennan8c24a812017-04-13 14:27:05 -0700543
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700544 config_count = 1
545 count = 0
546
Bindu Mahadev9c5a7d22018-07-16 12:08:35 -0700547 # For example, the NetworkSelector tests use 2 APs and require that
548 # both APs are not mirrored.
549 if not mirror_ap and ap_count == 1:
550 raise ValueError("ap_count cannot be 1 if mirror_ap is False.")
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700551
552 if not mirror_ap:
553 config_count = ap_count
554
555 self.user_params["reference_networks"] = []
556 self.user_params["open_network"] = []
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800557 if wpa_network:
558 self.user_params["wpa_networks"] = []
559 if wep_network:
560 self.user_params["wep_networks"] = []
Girish Moturudcd73f62018-10-18 09:49:32 -0700561 if ent_network:
562 self.user_params["ent_networks"] = []
Girish Moturuf1ce4202018-10-20 21:33:00 -0700563 if ent_network_pwd:
564 self.user_params["ent_networks_pwd"] = []
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700565
Girish Moturu25e8bb02019-08-28 17:17:41 -0700566 # kill hostapd & dhcpd if the cleanup was not successful
567 for i in range(len(self.access_points)):
568 self.log.debug("Check ap state and cleanup")
569 self._cleanup_hostapd_and_dhcpd(i)
570
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700571 for count in range(config_count):
572
573 network_list_2g = []
574 network_list_5g = []
575
576 orig_network_list_2g = []
577 orig_network_list_5g = []
578
579 network_list_2g.append({"channel": channel_2g})
580 network_list_5g.append({"channel": channel_5g})
581
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800582 networks_dict = self.get_psk_network(
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700583 mirror_ap,
584 self.user_params["reference_networks"],
585 hidden=hidden,
586 same_ssid=same_ssid)
587 self.reference_networks = self.user_params["reference_networks"]
588
Bindu Mahadev72725d12017-06-05 03:11:30 +0000589 network_list_2g.append(networks_dict["2g"])
590 network_list_5g.append(networks_dict["5g"])
Joe Brennan8c24a812017-04-13 14:27:05 -0700591
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700592 # When same_ssid is set, only configure one set of WPA networks.
593 # We cannot have more than one set because duplicate interface names
594 # are not allowed.
595 # TODO(bmahadev): Provide option to select the type of network,
596 # instead of defaulting to WPA.
597 if not same_ssid:
598 networks_dict = self.get_open_network(
599 mirror_ap,
600 self.user_params["open_network"],
601 hidden=hidden,
602 same_ssid=same_ssid)
603 self.open_network = self.user_params["open_network"]
Joe Brennan8c24a812017-04-13 14:27:05 -0700604
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700605 network_list_2g.append(networks_dict["2g"])
606 network_list_5g.append(networks_dict["5g"])
Bindu Mahadev1f227e02017-07-06 00:24:58 +0000607
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800608 if wpa_network:
609 networks_dict = self.get_psk_network(
610 mirror_ap,
611 self.user_params["wpa_networks"],
612 hidden=hidden,
613 same_ssid=same_ssid,
614 security_mode=hostapd_constants.WPA_STRING)
615 self.wpa_networks = self.user_params["wpa_networks"]
616
617 network_list_2g.append(networks_dict["2g"])
618 network_list_5g.append(networks_dict["5g"])
619
620 if wep_network:
621 networks_dict = self.get_wep_network(
622 mirror_ap,
623 self.user_params["wep_networks"],
624 hidden=hidden,
625 same_ssid=same_ssid)
626 self.wep_networks = self.user_params["wep_networks"]
627
628 network_list_2g.append(networks_dict["2g"])
629 network_list_5g.append(networks_dict["5g"])
630
Girish Moturudcd73f62018-10-18 09:49:32 -0700631 if ent_network:
632 networks_dict = self.get_open_network(
633 mirror_ap,
634 self.user_params["ent_networks"],
635 hidden=hidden,
636 same_ssid=same_ssid)
637 networks_dict["2g"]["security"] = hostapd_constants.ENT_STRING
638 networks_dict["2g"].update(radius_conf_2g)
639 networks_dict["5g"]["security"] = hostapd_constants.ENT_STRING
640 networks_dict["5g"].update(radius_conf_5g)
641 self.ent_networks = self.user_params["ent_networks"]
642
643 network_list_2g.append(networks_dict["2g"])
644 network_list_5g.append(networks_dict["5g"])
645
Girish Moturuf1ce4202018-10-20 21:33:00 -0700646 if ent_network_pwd:
647 networks_dict = self.get_open_network(
648 mirror_ap,
649 self.user_params["ent_networks_pwd"],
650 hidden=hidden,
651 same_ssid=same_ssid)
652 networks_dict["2g"]["security"] = hostapd_constants.ENT_STRING
653 networks_dict["2g"].update(radius_conf_pwd)
654 networks_dict["5g"]["security"] = hostapd_constants.ENT_STRING
655 networks_dict["5g"].update(radius_conf_pwd)
656 self.ent_networks_pwd = self.user_params["ent_networks_pwd"]
657
658 network_list_2g.append(networks_dict["2g"])
659 network_list_5g.append(networks_dict["5g"])
660
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700661 orig_network_list_5g = copy.copy(network_list_5g)
662 orig_network_list_2g = copy.copy(network_list_2g)
663
664 if len(network_list_5g) > 1:
665 self.config_5g = self._generate_legacy_ap_config(network_list_5g)
666 if len(network_list_2g) > 1:
667 self.config_2g = self._generate_legacy_ap_config(network_list_2g)
668
669 self.access_points[count].start_ap(self.config_2g)
670 self.access_points[count].start_ap(self.config_5g)
671 self.populate_bssid(count, self.access_points[count], orig_network_list_5g,
Bindu Mahadev2ebdcec2018-05-03 19:51:24 +0000672 orig_network_list_2g)
Bindu Mahadev72725d12017-06-05 03:11:30 +0000673
Bindu Mahadeve7d47c32018-07-03 16:48:03 -0700674 # Repeat configuration on the second router.
675 if mirror_ap and ap_count == 2:
676 self.access_points[AP_2].start_ap(self.config_2g)
677 self.access_points[AP_2].start_ap(self.config_5g)
678 self.populate_bssid(AP_2, self.access_points[AP_2],
679 orig_network_list_5g, orig_network_list_2g)
680
Girish Moturu27ff0b32019-08-03 21:44:59 -0700681 def _kill_processes(self, ap, daemon):
682 """ Kill hostapd and dhcpd daemons
683
684 Args:
685 ap: AP to cleanup
686 daemon: process to kill
687
688 Returns: True/False if killing process is successful
689 """
690 self.log.info("Killing %s" % daemon)
691 pids = ap.ssh.run('pidof %s' % daemon, ignore_status=True)
692 if pids.stdout:
693 ap.ssh.run('kill %s' % pids.stdout, ignore_status=True)
694 time.sleep(3)
695 pids = ap.ssh.run('pidof %s' % daemon, ignore_status=True)
696 if pids.stdout:
697 return False
698 return True
699
700 def _cleanup_hostapd_and_dhcpd(self, count):
701 """ Check if AP was cleaned up properly
702
703 Kill hostapd and dhcpd processes if cleanup was not successful in the
704 last run
705
706 Args:
707 count: AP to check
708
709 Returns:
710 New AccessPoint object if AP required cleanup
711
712 Raises:
713 Error: if the AccessPoint timed out to setup
714 """
715 ap = self.access_points[count]
716 phy_ifaces = ap.interfaces.get_physical_interface()
717 kill_hostapd = False
718 for iface in phy_ifaces:
719 if '2g_' in iface or '5g_' in iface or 'xg_' in iface:
720 kill_hostapd = True
721 break
722
723 if not kill_hostapd:
724 return
725
726 self.log.debug("Cleanup AP")
727 if not self._kill_processes(ap, 'hostapd') or \
728 not self._kill_processes(ap, 'dhcpd'):
729 raise("Failed to cleanup AP")
730
731 ap.__init__(self.user_params['AccessPoint'][count])
732
Joe Brennan8c24a812017-04-13 14:27:05 -0700733 def _generate_legacy_ap_config(self, network_list):
734 bss_settings = []
Bindu Mahadev071af262018-10-17 16:42:06 -0700735 wlan_2g = self.access_points[AP_1].wlan_2g
736 wlan_5g = self.access_points[AP_1].wlan_5g
Joe Brennan8c24a812017-04-13 14:27:05 -0700737 ap_settings = network_list.pop(0)
Bindu Mahadev1f227e02017-07-06 00:24:58 +0000738 # TODO:(bmahadev) This is a bug. We should not have to pop the first
739 # network in the list and treat it as a separate case. Instead,
740 # create_ap_preset() should be able to take NULL ssid and security and
741 # build config based on the bss_Settings alone.
Joe Brennan8c24a812017-04-13 14:27:05 -0700742 hostapd_config_settings = network_list.pop(0)
743 for network in network_list:
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800744 if "password" in network:
Bindu Mahadev1c895c22018-01-18 18:20:43 -0800745 bss_settings.append(
746 hostapd_bss_settings.BssSettings(
747 name=network["SSID"],
748 ssid=network["SSID"],
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800749 hidden=network["hiddenSSID"],
Bindu Mahadev1c895c22018-01-18 18:20:43 -0800750 security=hostapd_security.Security(
751 security_mode=network["security"],
752 password=network["password"])))
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800753 elif "wepKeys" in network:
754 bss_settings.append(
755 hostapd_bss_settings.BssSettings(
756 name=network["SSID"],
757 ssid=network["SSID"],
758 hidden=network["hiddenSSID"],
759 security=hostapd_security.Security(
760 security_mode=network["security"],
761 password=network["wepKeys"][0])))
Girish Moturudcd73f62018-10-18 09:49:32 -0700762 elif network["security"] == hostapd_constants.ENT_STRING:
763 bss_settings.append(
764 hostapd_bss_settings.BssSettings(
765 name=network["SSID"],
766 ssid=network["SSID"],
767 hidden=network["hiddenSSID"],
768 security=hostapd_security.Security(
769 security_mode=network["security"],
770 radius_server_ip=network["radius_server_ip"],
771 radius_server_port=network["radius_server_port"],
772 radius_server_secret=network["radius_server_secret"])))
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800773 else:
Joe Brennan8c24a812017-04-13 14:27:05 -0700774 bss_settings.append(
775 hostapd_bss_settings.BssSettings(
Bindu Mahadev72725d12017-06-05 03:11:30 +0000776 name=network["SSID"],
777 ssid=network["SSID"],
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800778 hidden=network["hiddenSSID"]))
Bindu Mahadev72725d12017-06-05 03:11:30 +0000779 if "password" in hostapd_config_settings:
Joe Brennan8c24a812017-04-13 14:27:05 -0700780 config = hostapd_ap_preset.create_ap_preset(
Bindu Mahadev071af262018-10-17 16:42:06 -0700781 iface_wlan_2g=wlan_2g,
782 iface_wlan_5g=wlan_5g,
Joe Brennan8c24a812017-04-13 14:27:05 -0700783 channel=ap_settings["channel"],
Bindu Mahadev72725d12017-06-05 03:11:30 +0000784 ssid=hostapd_config_settings["SSID"],
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800785 hidden=hostapd_config_settings["hiddenSSID"],
Joe Brennan8c24a812017-04-13 14:27:05 -0700786 security=hostapd_security.Security(
787 security_mode=hostapd_config_settings["security"],
Bindu Mahadev72725d12017-06-05 03:11:30 +0000788 password=hostapd_config_settings["password"]),
Bindu Mahadev071af262018-10-17 16:42:06 -0700789 bss_settings=bss_settings)
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800790 elif "wepKeys" in hostapd_config_settings:
791 config = hostapd_ap_preset.create_ap_preset(
Bindu Mahadev071af262018-10-17 16:42:06 -0700792 iface_wlan_2g=wlan_2g,
793 iface_wlan_5g=wlan_5g,
Hsiu-Chang Chen81061752018-08-15 13:49:23 +0800794 channel=ap_settings["channel"],
795 ssid=hostapd_config_settings["SSID"],
796 hidden=hostapd_config_settings["hiddenSSID"],
797 security=hostapd_security.Security(
798 security_mode=hostapd_config_settings["security"],
799 password=hostapd_config_settings["wepKeys"][0]),
Bindu Mahadev071af262018-10-17 16:42:06 -0700800 bss_settings=bss_settings)
Joe Brennan8c24a812017-04-13 14:27:05 -0700801 else:
802 config = hostapd_ap_preset.create_ap_preset(
Bindu Mahadev071af262018-10-17 16:42:06 -0700803 iface_wlan_2g=wlan_2g,
804 iface_wlan_5g=wlan_5g,
Joe Brennan8c24a812017-04-13 14:27:05 -0700805 channel=ap_settings["channel"],
Bindu Mahadev72725d12017-06-05 03:11:30 +0000806 ssid=hostapd_config_settings["SSID"],
Hsiu-Chang Chen8d8bbbf2018-08-02 11:37:11 +0800807 hidden=hostapd_config_settings["hiddenSSID"],
Bindu Mahadev071af262018-10-17 16:42:06 -0700808 bss_settings=bss_settings)
Joe Brennan8c24a812017-04-13 14:27:05 -0700809 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -0700810
811 def configure_packet_capture(
812 self,
813 channel_5g=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
814 channel_2g=hostapd_constants.AP_DEFAULT_CHANNEL_2G):
815 """Configure packet capture for 2G and 5G bands.
816
817 Args:
818 channel_5g: Channel to set the monitor mode to for 5G band.
819 channel_2g: Channel to set the monitor mode to for 2G band.
820 """
821 self.packet_capture = self.packet_capture[0]
822 result = self.packet_capture.configure_monitor_mode(
823 hostapd_constants.BAND_2G, channel_2g)
824 if not result:
825 raise ValueError("Failed to configure channel for 2G band")
826
827 result = self.packet_capture.configure_monitor_mode(
828 hostapd_constants.BAND_5G, channel_5g)
829 if not result:
830 raise ValueError("Failed to configure channel for 5G band.")
Girish Moturue6ccc7a2019-09-19 11:00:21 -0700831
832 @staticmethod
833 def wifi_test_wrap(fn):
834 def _safe_wrap_test_case(self, *args, **kwargs):
835 test_id = "%s:%s:%s" % (self.__class__.__name__, self.test_name,
836 self.log_begin_time.replace(' ', '-'))
837 self.test_id = test_id
838 self.result_detail = ""
839 tries = int(self.user_params.get("wifi_auto_rerun", 3))
840 for ad in self.android_devices:
841 ad.log_path = self.log_path
842 for i in range(tries + 1):
843 result = True
844 if i > 0:
845 log_string = "[Test Case] RETRY:%s %s" % (i, self.test_name)
846 self.log.info(log_string)
847 self._teardown_test(self.test_name)
848 self._setup_test(self.test_name)
849 try:
850 result = fn(self, *args, **kwargs)
851 except signals.TestFailure as e:
852 self.log.warn("Error msg: %s" % e)
853 if self.result_detail:
854 signal.details = self.result_detail
855 result = False
856 except signals.TestSignal:
857 if self.result_detail:
858 signal.details = self.result_detail
859 raise
860 except Exception as e:
861 self.log.exception(e)
862 asserts.fail(self.result_detail)
863 if result is False:
864 if i < tries:
865 continue
866 else:
867 break
868 if result is not False:
869 asserts.explicit_pass(self.result_detail)
870 else:
871 asserts.fail(self.result_detail)
872
873 return _safe_wrap_test_case