blob: 6a55cacb01b575d80f3cf6f5521c33d52cc94adc [file] [log] [blame]
Mark De Ruyter1a7ae572018-03-02 15:35:36 -08001#!/usr/bin/env python3
Ang Li73697b32015-12-03 00:41:53 +00002#
tturney1bdf77d2015-12-28 17:46:13 -08003# Copyright 2016 Google, Inc.
Ang Li73697b32015-12-03 00:41:53 +00004#
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
Ang Li5bd83f32016-05-23 14:39:38 -070017import logging
Girish Moturucf4dccd2018-08-27 12:22:00 -070018import os
James Mattis5a5dd492020-05-14 13:09:43 -070019import re
xianyuanjia0431ba32018-12-14 09:56:42 -080020import shutil
Girish Moturucf4dccd2018-08-27 12:22:00 -070021import time
Ang Li73697b32015-12-03 00:41:53 +000022
“Alfie90ee7cb2021-04-20 23:16:12 +080023from retry import retry
24
David Sue4cd9c22019-03-26 18:07:26 -070025from collections import namedtuple
Ang Li73697b32015-12-03 00:41:53 +000026from enum import IntEnum
27from queue import Empty
28
Ang Li82522812016-06-02 13:57:21 -070029from acts import asserts
Xianyuan Jia0e39e552019-01-24 17:17:47 -080030from acts import context
Ang Li374d7602016-02-08 17:27:27 -080031from acts import signals
Ang Lifee28402016-07-13 13:43:29 -070032from acts import utils
Ang Li2d3fe982016-06-08 10:00:43 -070033from acts.controllers import attenuator
Bindu Mahadev7e5dc682019-02-01 16:53:34 -080034from acts.controllers.ap_lib import hostapd_security
35from acts.controllers.ap_lib import hostapd_ap_preset
Girish Moturucf4dccd2018-08-27 12:22:00 -070036from acts.controllers.ap_lib.hostapd_constants import BAND_2G
37from acts.controllers.ap_lib.hostapd_constants import BAND_5G
Roshan Pius5fd42eb2021-01-21 12:26:31 -080038from acts_contrib.test_utils.net import connectivity_const as cconsts
Xianyuan Jia63751fb2020-11-17 00:07:40 +000039from acts_contrib.test_utils.tel import tel_defines
Roshan Pius5fd42eb2021-01-21 12:26:31 -080040from acts_contrib.test_utils.wifi import wifi_constants
41from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils
Ang Li73697b32015-12-03 00:41:53 +000042
Bindu Mahadev1d3991e2017-03-20 18:06:54 -070043# Default timeout used for reboot, toggle WiFi and Airplane mode,
44# for the system to settle down after the operation.
45DEFAULT_TIMEOUT = 10
Ang Li73697b32015-12-03 00:41:53 +000046# Number of seconds to wait for events that are supposed to happen quickly.
47# Like onSuccess for start background scan and confirmation on wifi state
48# change.
49SHORT_TIMEOUT = 30
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070050ROAMING_TIMEOUT = 30
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -080051WIFI_CONNECTION_TIMEOUT_DEFAULT = 30
Ang Li73697b32015-12-03 00:41:53 +000052# Speed of light in m/s.
53SPEED_OF_LIGHT = 299792458
54
Qi Jiang8b443672018-03-16 14:46:50 -070055DEFAULT_PING_ADDR = "https://www.google.com/robots.txt"
Ang Li73697b32015-12-03 00:41:53 +000056
Girish Moturuddc0d382020-08-24 12:08:41 -070057CNSS_DIAG_CONFIG_PATH = "/data/vendor/wifi/cnss_diag/"
58CNSS_DIAG_CONFIG_FILE = "cnss_diag.conf"
59
Girish Moturu36348a32019-12-10 08:41:54 -080060ROAMING_ATTN = {
Omar El Ayach8c017902020-10-18 10:26:57 -070061 "AP1_on_AP2_off": [0, 0, 95, 95],
62 "AP1_off_AP2_on": [95, 95, 0, 0],
63 "default": [0, 0, 0, 0]
64}
Ang Li82522812016-06-02 13:57:21 -070065
Xianyuan Jia0e39e552019-01-24 17:17:47 -080066
Ang Li73697b32015-12-03 00:41:53 +000067class WifiEnums():
68
Omar El Ayach8c017902020-10-18 10:26:57 -070069 SSID_KEY = "SSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080070 SSID_PATTERN_KEY = "ssidPattern"
Bindu Mahadev4c94b532019-01-09 12:20:10 -080071 NETID_KEY = "network_id"
Omar El Ayach8c017902020-10-18 10:26:57 -070072 BSSID_KEY = "BSSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080073 BSSID_PATTERN_KEY = "bssidPattern"
Omar El Ayach8c017902020-10-18 10:26:57 -070074 PWD_KEY = "password" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000075 frequency_key = "frequency"
Omar El Ayach8c017902020-10-18 10:26:57 -070076 HIDDEN_KEY = "hiddenSSID" # Used for Wifi & SoftAp
Roshan Piusd1204442018-11-12 12:20:39 -080077 IS_APP_INTERACTION_REQUIRED = "isAppInteractionRequired"
78 IS_USER_INTERACTION_REQUIRED = "isUserInteractionRequired"
Roshan Pius55fb7c42020-04-03 14:47:18 -070079 IS_SUGGESTION_METERED = "isMetered"
Roshan Piusd1204442018-11-12 12:20:39 -080080 PRIORITY = "priority"
Omar El Ayach8c017902020-10-18 10:26:57 -070081 SECURITY = "security" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000082
leslce9cf6d2020-02-19 16:37:07 +080083 # Used for SoftAp
lesl6d30a172020-03-05 15:05:22 +080084 AP_BAND_KEY = "apBand"
85 AP_CHANNEL_KEY = "apChannel"
lesl67124362021-05-04 19:33:14 +080086 AP_BANDS_KEY = "apBands"
87 AP_CHANNEL_FREQUENCYS_KEY = "apChannelFrequencies"
88 AP_MAC_RANDOMIZATION_SETTING_KEY = "MacRandomizationSetting"
89 AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY = "BridgedModeOpportunisticShutdownEnabled"
90 AP_IEEE80211AX_ENABLED_KEY = "Ieee80211axEnabled"
lesl6d30a172020-03-05 15:05:22 +080091 AP_MAXCLIENTS_KEY = "MaxNumberOfClients"
92 AP_SHUTDOWNTIMEOUT_KEY = "ShutdownTimeoutMillis"
93 AP_SHUTDOWNTIMEOUTENABLE_KEY = "AutoShutdownEnabled"
94 AP_CLIENTCONTROL_KEY = "ClientControlByUserEnabled"
95 AP_ALLOWEDLIST_KEY = "AllowedClientList"
96 AP_BLOCKEDLIST_KEY = "BlockedClientList"
97
leslce9cf6d2020-02-19 16:37:07 +080098 WIFI_CONFIG_SOFTAP_BAND_2G = 1
99 WIFI_CONFIG_SOFTAP_BAND_5G = 2
100 WIFI_CONFIG_SOFTAP_BAND_2G_5G = 3
101 WIFI_CONFIG_SOFTAP_BAND_6G = 4
102 WIFI_CONFIG_SOFTAP_BAND_2G_6G = 5
103 WIFI_CONFIG_SOFTAP_BAND_5G_6G = 6
104 WIFI_CONFIG_SOFTAP_BAND_ANY = 7
105
106 # DO NOT USE IT for new test case! Replaced by WIFI_CONFIG_SOFTAP_BAND_
107 WIFI_CONFIG_APBAND_2G = WIFI_CONFIG_SOFTAP_BAND_2G
108 WIFI_CONFIG_APBAND_5G = WIFI_CONFIG_SOFTAP_BAND_5G
109 WIFI_CONFIG_APBAND_AUTO = WIFI_CONFIG_SOFTAP_BAND_2G_5G
110
111 WIFI_CONFIG_APBAND_2G_OLD = 0
112 WIFI_CONFIG_APBAND_5G_OLD = 1
113 WIFI_CONFIG_APBAND_AUTO_OLD = -1
Ang Li73697b32015-12-03 00:41:53 +0000114
Ang Li82522812016-06-02 13:57:21 -0700115 WIFI_WPS_INFO_PBC = 0
116 WIFI_WPS_INFO_DISPLAY = 1
117 WIFI_WPS_INFO_KEYPAD = 2
118 WIFI_WPS_INFO_LABEL = 3
119 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +0000120
lesl6d30a172020-03-05 15:05:22 +0800121 class SoftApSecurityType():
122 OPEN = "NONE"
123 WPA2 = "WPA2_PSK"
124 WPA3_SAE_TRANSITION = "WPA3_SAE_TRANSITION"
125 WPA3_SAE = "WPA3_SAE"
126
Ang Li73697b32015-12-03 00:41:53 +0000127 class CountryCode():
Girish Moturue648b6a2021-03-04 13:52:15 -0800128 AUSTRALIA = "AU"
Ang Li73697b32015-12-03 00:41:53 +0000129 CHINA = "CN"
Girish Moturua5ef35d2020-10-19 14:58:01 -0700130 GERMANY = "DE"
Ang Li73697b32015-12-03 00:41:53 +0000131 JAPAN = "JP"
132 UK = "GB"
133 US = "US"
134 UNKNOWN = "UNKNOWN"
135
136 # Start of Macros for EAP
137 # EAP types
138 class Eap(IntEnum):
139 NONE = -1
140 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -0700141 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +0000142 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -0700143 PWD = 3
144 SIM = 4
145 AKA = 5
146 AKA_PRIME = 6
147 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +0000148
149 # EAP Phase2 types
150 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700151 NONE = 0
152 PAP = 1
153 MSCHAP = 2
154 MSCHAPV2 = 3
155 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +0000156
157 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -0700158 # Enterprise Config Macros
159 EMPTY_VALUE = "NULL"
160 EAP = "eap"
161 PHASE2 = "phase2"
162 IDENTITY = "identity"
163 ANON_IDENTITY = "anonymous_identity"
164 PASSWORD = "password"
165 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000166 ALTSUBJECT_MATCH = "altsubject_match"
167 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700168 CLIENT_CERT = "client_cert"
169 CA_CERT = "ca_cert"
170 ENGINE = "engine"
171 ENGINE_ID = "engine_id"
172 PRIVATE_KEY_ID = "key_id"
173 REALM = "realm"
174 PLMN = "plmn"
175 FQDN = "FQDN"
176 FRIENDLY_NAME = "providerFriendlyName"
177 ROAMING_IDS = "roamingConsortiumIds"
Jimmy Chen7baec622020-06-23 19:00:33 +0800178 OCSP = "ocsp"
Omar El Ayach8c017902020-10-18 10:26:57 -0700179
Ang Li73697b32015-12-03 00:41:53 +0000180 # End of Macros for EAP
181
182 # Macros for wifi p2p.
183 WIFI_P2P_SERVICE_TYPE_ALL = 0
184 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
185 WIFI_P2P_SERVICE_TYPE_UPNP = 2
186 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
187
188 class ScanResult:
189 CHANNEL_WIDTH_20MHZ = 0
190 CHANNEL_WIDTH_40MHZ = 1
191 CHANNEL_WIDTH_80MHZ = 2
192 CHANNEL_WIDTH_160MHZ = 3
193 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
194
195 # Macros for wifi rtt.
196 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700197 TYPE_ONE_SIDED = 1
198 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000199
200 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700201 PEER_TYPE_AP = 1
202 PEER_TYPE_STA = 2 # Requires NAN.
203 PEER_P2P_GO = 3
204 PEER_P2P_CLIENT = 4
205 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000206
207 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700208 PREAMBLE_LEGACY = 0x01
209 PREAMBLE_HT = 0x02
210 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000211
212 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700213 BW_5_SUPPORT = 0x01
214 BW_10_SUPPORT = 0x02
215 BW_20_SUPPORT = 0x04
216 BW_40_SUPPORT = 0x08
217 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000218 BW_160_SUPPORT = 0x20
219
220 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700221 STATUS_SUCCESS = 0
222 STATUS_FAILURE = 1
223 STATUS_FAIL_NO_RSP = 2
224 STATUS_FAIL_REJECTED = 3
225 STATUS_FAIL_NOT_SCHEDULED_YET = 4
226 STATUS_FAIL_TM_TIMEOUT = 5
227 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
228 STATUS_FAIL_NO_CAPABILITY = 7
229 STATUS_ABORTED = 8
230 STATUS_FAIL_INVALID_TS = 9
231 STATUS_FAIL_PROTOCOL = 10
232 STATUS_FAIL_SCHEDULE = 11
233 STATUS_FAIL_BUSY_TRY_LATER = 12
234 STATUS_INVALID_REQ = 13
235 STATUS_NO_WIFI = 14
236 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000237
Ang Li82522812016-06-02 13:57:21 -0700238 REASON_UNSPECIFIED = -1
239 REASON_NOT_AVAILABLE = -2
240 REASON_INVALID_LISTENER = -3
241 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000242
243 class RttParam:
244 device_type = "deviceType"
245 request_type = "requestType"
246 BSSID = "bssid"
247 channel_width = "channelWidth"
248 frequency = "frequency"
249 center_freq0 = "centerFreq0"
250 center_freq1 = "centerFreq1"
251 number_burst = "numberBurst"
252 interval = "interval"
253 num_samples_per_burst = "numSamplesPerBurst"
254 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
255 num_retries_per_FTMR = "numRetriesPerFTMR"
256 lci_request = "LCIRequest"
257 lcr_request = "LCRRequest"
258 burst_timeout = "burstTimeout"
259 preamble = "preamble"
260 bandwidth = "bandwidth"
261 margin = "margin"
262
263 RTT_MARGIN_OF_ERROR = {
264 RttBW.BW_80_SUPPORT: 2,
265 RttBW.BW_40_SUPPORT: 5,
266 RttBW.BW_20_SUPPORT: 5
267 }
268
269 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700270 WIFI_BAND_UNSPECIFIED = 0 # not specified
271 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
272 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
273 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
274 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
275 WIFI_BAND_BOTH = 3 # both bands without DFS channels
276 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000277
278 REPORT_EVENT_AFTER_BUFFER_FULL = 0
279 REPORT_EVENT_AFTER_EACH_SCAN = 1
280 REPORT_EVENT_FULL_SCAN_RESULT = 2
281
xshuaabcfeb2018-02-14 11:43:24 -0800282 SCAN_TYPE_LOW_LATENCY = 0
283 SCAN_TYPE_LOW_POWER = 1
284 SCAN_TYPE_HIGH_ACCURACY = 2
285
Ang Li73697b32015-12-03 00:41:53 +0000286 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700287 ALL_2G_FREQUENCIES = [
288 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
289 ]
290 DFS_5G_FREQUENCIES = [
291 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640,
292 5660, 5680, 5700, 5720
293 ]
294 NONE_DFS_5G_FREQUENCIES = [
295 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
296 ]
Ang Li73697b32015-12-03 00:41:53 +0000297 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
298
299 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700300 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
301 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
302 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
303 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
304 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
305 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000306 }
307
308 # All Wifi frequencies to channels lookup.
309 freq_to_channel = {
310 2412: 1,
311 2417: 2,
312 2422: 3,
313 2427: 4,
314 2432: 5,
315 2437: 6,
316 2442: 7,
317 2447: 8,
318 2452: 9,
319 2457: 10,
320 2462: 11,
321 2467: 12,
322 2472: 13,
323 2484: 14,
324 4915: 183,
325 4920: 184,
326 4925: 185,
327 4935: 187,
328 4940: 188,
329 4945: 189,
330 4960: 192,
331 4980: 196,
332 5035: 7,
333 5040: 8,
334 5045: 9,
335 5055: 11,
336 5060: 12,
337 5080: 16,
338 5170: 34,
339 5180: 36,
340 5190: 38,
341 5200: 40,
342 5210: 42,
343 5220: 44,
344 5230: 46,
345 5240: 48,
346 5260: 52,
347 5280: 56,
348 5300: 60,
349 5320: 64,
350 5500: 100,
351 5520: 104,
352 5540: 108,
353 5560: 112,
354 5580: 116,
355 5600: 120,
356 5620: 124,
357 5640: 128,
358 5660: 132,
359 5680: 136,
360 5700: 140,
361 5745: 149,
362 5765: 153,
363 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700364 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000365 5805: 161,
366 5825: 165,
367 }
368
369 # All Wifi channels to frequencies lookup.
370 channel_2G_to_freq = {
371 1: 2412,
372 2: 2417,
373 3: 2422,
374 4: 2427,
375 5: 2432,
376 6: 2437,
377 7: 2442,
378 8: 2447,
379 9: 2452,
380 10: 2457,
381 11: 2462,
382 12: 2467,
383 13: 2472,
384 14: 2484
385 }
386
387 channel_5G_to_freq = {
388 183: 4915,
389 184: 4920,
390 185: 4925,
391 187: 4935,
392 188: 4940,
393 189: 4945,
394 192: 4960,
395 196: 4980,
396 7: 5035,
397 8: 5040,
398 9: 5045,
399 11: 5055,
400 12: 5060,
401 16: 5080,
402 34: 5170,
403 36: 5180,
404 38: 5190,
405 40: 5200,
406 42: 5210,
407 44: 5220,
408 46: 5230,
409 48: 5240,
Omar El Ayach8c017902020-10-18 10:26:57 -0700410 50: 5250,
Ang Li73697b32015-12-03 00:41:53 +0000411 52: 5260,
412 56: 5280,
413 60: 5300,
414 64: 5320,
415 100: 5500,
416 104: 5520,
417 108: 5540,
418 112: 5560,
419 116: 5580,
420 120: 5600,
421 124: 5620,
422 128: 5640,
423 132: 5660,
424 136: 5680,
425 140: 5700,
426 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700427 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000428 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700429 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000430 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700431 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000432 161: 5805,
433 165: 5825
434 }
435
Ang Li82522812016-06-02 13:57:21 -0700436
Ang Li73697b32015-12-03 00:41:53 +0000437class WifiChannelBase:
438 ALL_2G_FREQUENCIES = []
439 DFS_5G_FREQUENCIES = []
440 NONE_DFS_5G_FREQUENCIES = []
441 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
442 MIX_CHANNEL_SCAN = []
443
444 def band_to_freq(self, band):
445 _band_to_frequencies = {
Omar El Ayach8c017902020-10-18 10:26:57 -0700446 WifiEnums.WIFI_BAND_24_GHZ:
447 self.ALL_2G_FREQUENCIES,
448 WifiEnums.WIFI_BAND_5_GHZ:
449 self.NONE_DFS_5G_FREQUENCIES,
450 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY:
451 self.DFS_5G_FREQUENCIES,
452 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS:
453 self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700454 WifiEnums.WIFI_BAND_BOTH:
455 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
456 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
457 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000458 }
459 return _band_to_frequencies[band]
460
Ang Li82522812016-06-02 13:57:21 -0700461
Ang Li73697b32015-12-03 00:41:53 +0000462class WifiChannelUS(WifiChannelBase):
463 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700464 ALL_2G_FREQUENCIES = [
465 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
466 ]
467 NONE_DFS_5G_FREQUENCIES = [
468 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
469 ]
470 MIX_CHANNEL_SCAN = [
471 2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500, 5320, 5520, 5560,
472 5700, 5745, 5805
473 ]
Ang Li73697b32015-12-03 00:41:53 +0000474
475 def __init__(self, model=None):
Omar El Ayach8c017902020-10-18 10:26:57 -0700476 self.DFS_5G_FREQUENCIES = [
477 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620,
478 5640, 5660, 5680, 5700, 5720
479 ]
Girish Moturu0c567b02017-08-11 16:20:01 -0700480 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000481
Bindu Mahadevff295782019-02-08 16:17:48 -0800482
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530483class WifiReferenceNetworks:
484 """ Class to parse and return networks of different band and
485 auth type from reference_networks
486 """
487 def __init__(self, obj):
488 self.reference_networks = obj
489 self.WIFI_2G = "2g"
490 self.WIFI_5G = "5g"
491
492 self.secure_networks_2g = []
493 self.secure_networks_5g = []
494 self.open_networks_2g = []
495 self.open_networks_5g = []
496 self._parse_networks()
497
498 def _parse_networks(self):
499 for network in self.reference_networks:
500 for key in network:
501 if key == self.WIFI_2G:
502 if "password" in network[key]:
503 self.secure_networks_2g.append(network[key])
504 else:
505 self.open_networks_2g.append(network[key])
506 else:
507 if "password" in network[key]:
508 self.secure_networks_5g.append(network[key])
509 else:
510 self.open_networks_5g.append(network[key])
511
512 def return_2g_secure_networks(self):
513 return self.secure_networks_2g
514
515 def return_5g_secure_networks(self):
516 return self.secure_networks_5g
517
518 def return_2g_open_networks(self):
519 return self.open_networks_2g
520
521 def return_5g_open_networks(self):
522 return self.open_networks_5g
523
524 def return_secure_networks(self):
525 return self.secure_networks_2g + self.secure_networks_5g
526
527 def return_open_networks(self):
528 return self.open_networks_2g + self.open_networks_5g
529
Ang Li82522812016-06-02 13:57:21 -0700530
531def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
532 """Wrapper function that handles the bahevior of assert_on_fail.
533
534 When assert_on_fail is True, let all test signals through, which can
535 terminate test cases directly. When assert_on_fail is False, the wrapper
536 raises no test signals and reports operation status by returning True or
537 False.
538
539 Args:
540 func: The function to wrap. This function reports operation status by
541 raising test signals.
542 assert_on_fail: A boolean that specifies if the output of the wrapper
543 is test signal based or return value based.
544 args: Positional args for func.
545 kwargs: Name args for func.
546
547 Returns:
548 If assert_on_fail is True, returns True/False to signal operation
549 status, otherwise return nothing.
550 """
551 try:
552 func(*args, **kwargs)
553 if not assert_on_fail:
554 return True
555 except signals.TestSignal:
556 if assert_on_fail:
557 raise
558 return False
559
560
561def assert_network_in_list(target, network_list):
562 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
563 networks.
564
565 Args:
566 target: A dict representing a Wi-Fi network.
567 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
568 network_list: A list of dicts, each representing a Wi-Fi network.
569 """
570 match_results = match_networks(target, network_list)
571 asserts.assert_true(
572 match_results, "Target network %s, does not exist in network list %s" %
573 (target, network_list))
574
575
Ang Li73697b32015-12-03 00:41:53 +0000576def match_networks(target_params, networks):
577 """Finds the WiFi networks that match a given set of parameters in a list
578 of WiFi networks.
579
Girish Moturubc48d9f2016-11-01 13:24:14 -0700580 To be considered a match, the network should contain every key-value pair
581 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000582
583 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700584 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
585 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000586 networks: A list of dict objects representing WiFi networks.
587
588 Returns:
589 The networks that match the target parameters.
590 """
591 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800592 asserts.assert_true(target_params,
593 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000594 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700595 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800596 for k, v in target_params.items():
597 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700598 add_network = 0
599 break
Ang Li9a66de72016-02-08 15:26:38 -0800600 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700601 add_network = 0
602 break
603 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000604 results.append(n)
605 return results
606
Bindu Mahadevff295782019-02-08 16:17:48 -0800607
Roshan Pius93b519c2018-05-09 12:07:11 -0700608def wait_for_wifi_state(ad, state, assert_on_fail=True):
609 """Waits for the device to transition to the specified wifi state
610
611 Args:
612 ad: An AndroidDevice object.
613 state: Wifi state to wait for.
614 assert_on_fail: If True, error checks in this function will raise test
615 failure signals.
616
617 Returns:
618 If assert_on_fail is False, function returns True if the device transitions
619 to the specified state, False otherwise. If assert_on_fail is True, no return value.
620 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700621 return _assert_on_fail_handler(_wait_for_wifi_state,
622 assert_on_fail,
623 ad,
624 state=state)
Roshan Pius93b519c2018-05-09 12:07:11 -0700625
626
627def _wait_for_wifi_state(ad, state):
628 """Toggles the state of wifi.
629
630 TestFailure signals are raised when something goes wrong.
631
632 Args:
633 ad: An AndroidDevice object.
634 state: Wifi state to wait for.
635 """
636 if state == ad.droid.wifiCheckState():
637 # Check if the state is already achieved, so we don't wait for the
638 # state change event by mistake.
639 return
640 ad.droid.wifiStartTrackingStateChange()
Omar El Ayach8c017902020-10-18 10:26:57 -0700641 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (
642 state, ad.serial)
Roshan Pius93b519c2018-05-09 12:07:11 -0700643 try:
644 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
645 lambda x: x["data"]["enabled"] == state,
646 SHORT_TIMEOUT)
647 except Empty:
648 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
649 finally:
650 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700651
Bindu Mahadevff295782019-02-08 16:17:48 -0800652
Ang Li82522812016-06-02 13:57:21 -0700653def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800654 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000655
Ang Li6b557182015-11-11 17:19:17 -0800656 Args:
657 ad: An AndroidDevice object.
658 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700659 assert_on_fail: If True, error checks in this function will raise test
660 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000661
Ang Li6b557182015-11-11 17:19:17 -0800662 Returns:
Ang Li82522812016-06-02 13:57:21 -0700663 If assert_on_fail is False, function returns True if the toggle was
664 successful, False otherwise. If assert_on_fail is True, no return value.
665 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700666 return _assert_on_fail_handler(_wifi_toggle_state,
667 assert_on_fail,
668 ad,
669 new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700670
671
672def _wifi_toggle_state(ad, new_state=None):
673 """Toggles the state of wifi.
674
675 TestFailure signals are raised when something goes wrong.
676
677 Args:
678 ad: An AndroidDevice object.
679 new_state: The state to set Wi-Fi to. If None, opposite of the current
680 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800681 """
Ang Li31b00782016-06-21 13:04:23 -0700682 if new_state is None:
683 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700684 elif new_state == ad.droid.wifiCheckState():
685 # Check if the new_state is already achieved, so we don't wait for the
686 # state change event by mistake.
687 return
688 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700689 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700690 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700691 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800692 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800693 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700694 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
695 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000696 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700697 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
698 lambda x: x["data"]["enabled"] == new_state,
699 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000700 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700701 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800702 finally:
703 ad.droid.wifiStopTrackingStateChange()
704
Ang Li82522812016-06-02 13:57:21 -0700705
Ang Li6b557182015-11-11 17:19:17 -0800706def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700707 """Clears all saved Wi-Fi networks on a device.
708
709 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800710
711 Args:
712 ad: An AndroidDevice object.
713
Ang Li6b557182015-11-11 17:19:17 -0800714 """
Ang Li6b557182015-11-11 17:19:17 -0800715 networks = ad.droid.wifiGetConfiguredNetworks()
716 if not networks:
717 return
718 for n in networks:
719 ad.droid.wifiForgetNetwork(n['networkId'])
720 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800721 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700722 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800723 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700724 logging.warning("Could not confirm the removal of network %s.", n)
725 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800726 asserts.assert_true(
727 not ad.droid.wifiGetConfiguredNetworks(),
728 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700729
Ang Li73697b32015-12-03 00:41:53 +0000730
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700731def toggle_airplane_mode_on_and_off(ad):
732 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800733
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700734 ad: An AndroidDevice object.
735 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800736
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700737 """
738 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700739 asserts.assert_true(utils.force_airplane_mode(ad, True),
740 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700741 time.sleep(DEFAULT_TIMEOUT)
742 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700743 asserts.assert_true(utils.force_airplane_mode(ad, False),
744 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700745 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800746
747
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700748def toggle_wifi_off_and_on(ad):
749 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800750
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700751 ad: An AndroidDevice object.
752 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800753
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700754 """
755 ad.log.debug("Toggling wifi OFF.")
756 wifi_toggle_state(ad, False)
757 time.sleep(DEFAULT_TIMEOUT)
758 ad.log.debug("Toggling wifi ON.")
759 wifi_toggle_state(ad, True)
760 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800761
762
Ang Li73697b32015-12-03 00:41:53 +0000763def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800764 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000765
Ang Li8e767182015-12-09 17:29:24 -0800766 Args:
767 ad: android_device object for forget network.
768 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000769
Ang Li8e767182015-12-09 17:29:24 -0800770 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700771 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800772 if not networks:
773 return
774 for n in networks:
775 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700776 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800777 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800778 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800779 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800780 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700781 asserts.fail("Failed to remove network %s." % n)
Jimmy Chen8e40e152021-05-06 14:37:18 +0800782 break
Ang Li73697b32015-12-03 00:41:53 +0000783
Ang Li82522812016-06-02 13:57:21 -0700784
Ang Li73697b32015-12-03 00:41:53 +0000785def wifi_test_device_init(ad):
786 """Initializes an android device for wifi testing.
787
788 0. Make sure SL4A connection is established on the android device.
789 1. Disable location service's WiFi scan.
790 2. Turn WiFi on.
791 3. Clear all saved networks.
792 4. Set country code to US.
793 5. Enable WiFi verbose logging.
794 6. Sync device time with computer time.
795 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700796 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000797 """
Ang Lifee28402016-07-13 13:43:29 -0700798 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000799 ad.droid.wifiScannerToggleAlwaysAvailable(False)
800 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700801 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
802 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800803 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000804 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800805 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700806 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000807 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700808 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700809 output = ad.adb.shell(
810 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
811 "wlan0 log_level EXCESSIVE",
812 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700813 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700814 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800815 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700816 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700817 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000818
Omar El Ayach8c017902020-10-18 10:26:57 -0700819
Roshan Pius48df08c2019-09-13 08:07:30 -0700820def set_wifi_country_code(ad, country_code):
821 """Sets the wifi country code on the device.
822
823 Args:
824 ad: An AndroidDevice object.
825 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800826
827 Raises:
828 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700829 """
Jaineelc5b56a62019-10-10 17:12:02 -0700830 try:
codycaldwell35b87182020-01-16 14:08:01 -0800831 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000832 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700833 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700834
Ang Li82522812016-06-02 13:57:21 -0700835
Ang Li6b557182015-11-11 17:19:17 -0800836def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000837 """Starts a wifi connection scan and wait for results to become available.
838
839 Args:
Ang Li6b557182015-11-11 17:19:17 -0800840 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000841 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800842 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800843 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700844 try:
845 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
846 except Empty:
847 asserts.fail("Wi-Fi results did not become available within 60s.")
848
Ang Li73697b32015-12-03 00:41:53 +0000849
Roshan Piuscb9bc482018-02-01 14:27:09 -0800850def start_wifi_connection_scan_and_return_status(ad):
851 """
852 Starts a wifi connection scan and wait for results to become available
853 or a scan failure to be reported.
854
855 Args:
856 ad: An AndroidDevice object.
857 Returns:
858 True: if scan succeeded & results are available
859 False: if scan failed
860 """
861 ad.ed.clear_all_events()
862 ad.droid.wifiStartScan()
863 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700864 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
865 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800866 except Empty:
867 asserts.fail(
868 "Wi-Fi scan results/failure did not become available within 60s.")
869 # If there are multiple matches, we check for atleast one success.
870 for event in events:
871 if event["name"] == "WifiManagerScanResultsAvailable":
872 return True
873 elif event["name"] == "WifiManagerScanFailure":
874 ad.log.debug("Scan failure received")
875 return False
876
877
Omar El Ayach8c017902020-10-18 10:26:57 -0700878def start_wifi_connection_scan_and_check_for_network(ad,
879 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800880 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800881 """
882 Start connectivity scans & checks if the |network_ssid| is seen in
883 scan results. The method performs a max of |max_tries| connectivity scans
884 to find the network.
885
886 Args:
887 ad: An AndroidDevice object.
888 network_ssid: SSID of the network we are looking for.
889 max_tries: Number of scans to try.
890 Returns:
891 True: if network_ssid is found in scan results.
892 False: if network_ssid is not found in scan results.
893 """
jerrypcchen5cc385d2021-03-11 11:57:21 +0000894 start_time = time.time()
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800895 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800896 if start_wifi_connection_scan_and_return_status(ad):
897 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700898 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
899 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800900 if len(match_results) > 0:
jerrypcchen5cc385d2021-03-11 11:57:21 +0000901 ad.log.debug("Found network in %s seconds." %
902 (time.time() - start_time))
Roshan Piuscb9bc482018-02-01 14:27:09 -0800903 return True
jerrypcchen5cc385d2021-03-11 11:57:21 +0000904 ad.log.debug("Did not find network in %s seconds." %
905 (time.time() - start_time))
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800906 return False
907
908
Omar El Ayach8c017902020-10-18 10:26:57 -0700909def start_wifi_connection_scan_and_ensure_network_found(
910 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800911 """
912 Start connectivity scans & ensure the |network_ssid| is seen in
913 scan results. The method performs a max of |max_tries| connectivity scans
914 to find the network.
915 This method asserts on failure!
916
917 Args:
918 ad: An AndroidDevice object.
919 network_ssid: SSID of the network we are looking for.
920 max_tries: Number of scans to try.
921 """
922 ad.log.info("Starting scans to ensure %s is present", network_ssid)
923 assert_msg = "Failed to find " + network_ssid + " in scan results" \
924 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700925 asserts.assert_true(
926 start_wifi_connection_scan_and_check_for_network(
927 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800928
929
Omar El Ayach8c017902020-10-18 10:26:57 -0700930def start_wifi_connection_scan_and_ensure_network_not_found(
931 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800932 """
933 Start connectivity scans & ensure the |network_ssid| is not seen in
934 scan results. The method performs a max of |max_tries| connectivity scans
935 to find the network.
936 This method asserts on failure!
937
938 Args:
939 ad: An AndroidDevice object.
940 network_ssid: SSID of the network we are looking for.
941 max_tries: Number of scans to try.
942 """
943 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
944 assert_msg = "Found " + network_ssid + " in scan results" \
945 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700946 asserts.assert_false(
947 start_wifi_connection_scan_and_check_for_network(
948 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800949
950
Ang Li73697b32015-12-03 00:41:53 +0000951def start_wifi_background_scan(ad, scan_setting):
952 """Starts wifi background scan.
953
954 Args:
955 ad: android_device object to initiate connection on.
956 scan_setting: A dict representing the settings of the scan.
957
958 Returns:
959 If scan was started successfully, event data of success event is returned.
960 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700961 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
962 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800963 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000964 return event['data']
965
Ang Li82522812016-06-02 13:57:21 -0700966
Girish Moturu38b993c2021-03-25 13:03:50 -0700967def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
968 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000969 """Starts wifi tethering on an android_device.
970
971 Args:
972 ad: android_device to start wifi tethering on.
973 ssid: The SSID the soft AP should broadcast.
974 password: The password the soft AP should use.
975 band: The band the soft AP should be set on. It should be either
976 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800977 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700978 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000979
980 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700981 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000982 """
Ang Li82522812016-06-02 13:57:21 -0700983 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000984 if password:
985 config[WifiEnums.PWD_KEY] = password
986 if band:
lesl6d30a172020-03-05 15:05:22 +0800987 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800988 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -0700989 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -0700990 if security:
991 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -0700992 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
993 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700994 ad.droid.wifiStartTrackingTetherStateChange()
995 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700996 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700997 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
998 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800999 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -07001000 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001001 except Empty:
1002 msg = "Failed to receive confirmation of wifi tethering starting"
1003 asserts.fail(msg)
1004 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001005 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001006
Bindu Mahadevff295782019-02-08 16:17:48 -08001007
Omar El Ayach8c017902020-10-18 10:26:57 -07001008def save_wifi_soft_ap_config(ad,
1009 wifi_config,
1010 band=None,
1011 hidden=None,
1012 security=None,
1013 password=None,
1014 channel=None,
1015 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001016 shutdown_timeout_enable=None,
1017 shutdown_timeout_millis=None,
1018 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001019 allowedList=None,
lesl67124362021-05-04 19:33:14 +08001020 blockedList=None,
1021 bands=None,
1022 channel_frequencys=None,
1023 mac_randomization_setting=None,
1024 bridged_opportunistic_shutdown_enabled=None,
1025 ieee80211ax_enabled=None):
lesl6d30a172020-03-05 15:05:22 +08001026 """ Save a soft ap configuration and verified
1027 Args:
1028 ad: android_device to set soft ap configuration.
1029 wifi_config: a soft ap configuration object, at least include SSID.
1030 band: specifies the band for the soft ap.
1031 hidden: specifies the soft ap need to broadcast its SSID or not.
1032 security: specifies the security type for the soft ap.
1033 password: specifies the password for the soft ap.
1034 channel: specifies the channel for the soft ap.
1035 max_clients: specifies the maximum connected client number.
1036 shutdown_timeout_enable: specifies the auto shut down enable or not.
1037 shutdown_timeout_millis: specifies the shut down timeout value.
1038 client_control_enable: specifies the client control enable or not.
1039 allowedList: specifies allowed clients list.
1040 blockedList: specifies blocked clients list.
lesl67124362021-05-04 19:33:14 +08001041 bands: specifies the band list for the soft ap.
1042 channel_frequencys: specifies the channel frequency list for soft ap.
1043 mac_randomization_setting: specifies the mac randomization setting.
1044 bridged_opportunistic_shutdown_enabled: specifies the opportunistic
1045 shutdown enable or not.
1046 ieee80211ax_enabled: specifies the ieee80211ax enable or not.
lesl6d30a172020-03-05 15:05:22 +08001047 """
1048 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001049 wifi_config[WifiEnums.SECURITY] = security
1050 wifi_config[WifiEnums.PWD_KEY] = password
lesl67124362021-05-04 19:33:14 +08001051 if hidden is not None:
Girish Moturu528b5442018-06-07 10:48:14 -07001052 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl67124362021-05-04 19:33:14 +08001053 if max_clients is not None:
lesl6d30a172020-03-05 15:05:22 +08001054 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
lesl67124362021-05-04 19:33:14 +08001055 if shutdown_timeout_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001056 wifi_config[
1057 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
lesl67124362021-05-04 19:33:14 +08001058 if shutdown_timeout_millis is not None:
Omar El Ayach8c017902020-10-18 10:26:57 -07001059 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl67124362021-05-04 19:33:14 +08001060 if client_control_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001061 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
lesl67124362021-05-04 19:33:14 +08001062 if allowedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001063 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
lesl67124362021-05-04 19:33:14 +08001064 if blockedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001065 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
lesl67124362021-05-04 19:33:14 +08001066 if mac_randomization_setting is not None:
1067 wifi_config[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY
1068 ] = mac_randomization_setting
1069 if bridged_opportunistic_shutdown_enabled is not None:
1070 wifi_config[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY
1071 ] = bridged_opportunistic_shutdown_enabled
1072 if ieee80211ax_enabled is not None:
1073 wifi_config[WifiEnums.AP_IEEE80211AX_ENABLED_KEY]= ieee80211ax_enabled
1074 if channel_frequencys is not None:
1075 wifi_config[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] = channel_frequencys
1076 elif bands is not None:
1077 wifi_config[WifiEnums.AP_BANDS_KEY] = bands
1078 elif band is not None:
1079 if channel is not None:
1080 wifi_config[WifiEnums.AP_BAND_KEY] = band
1081 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1082 else:
1083 wifi_config[WifiEnums.AP_BAND_KEY] = band
lesl6d30a172020-03-05 15:05:22 +08001084
1085 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001086 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001087 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1088
1089 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001090 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001091 del wifi_config[WifiEnums.SECURITY]
1092 del wifi_config[WifiEnums.PWD_KEY]
1093
Girish Moturu528b5442018-06-07 10:48:14 -07001094 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1095 "Failed to set WifiAp Configuration")
1096
1097 wifi_ap = ad.droid.wifiGetApConfiguration()
1098 asserts.assert_true(
1099 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001100 "Hotspot SSID doesn't match")
1101 if WifiEnums.SECURITY in wifi_config:
1102 asserts.assert_true(
1103 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1104 "Hotspot Security doesn't match")
1105 if WifiEnums.PWD_KEY in wifi_config:
1106 asserts.assert_true(
1107 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1108 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001109
lesl6d30a172020-03-05 15:05:22 +08001110 if WifiEnums.HIDDEN_KEY in wifi_config:
1111 asserts.assert_true(
1112 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1113 "Hotspot hidden setting doesn't match")
1114
lesl6d30a172020-03-05 15:05:22 +08001115 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1116 asserts.assert_true(
1117 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001118 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001119 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1120 asserts.assert_true(
1121 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001122 WifiEnums.AP_MAXCLIENTS_KEY],
1123 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001124 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1125 asserts.assert_true(
1126 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001127 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001128 "Hotspot ShutDown feature flag doesn't match")
1129 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1130 asserts.assert_true(
1131 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001132 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001133 "Hotspot ShutDown timeout setting doesn't match")
1134 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1135 asserts.assert_true(
1136 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001137 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001138 "Hotspot Client control flag doesn't match")
1139 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1140 asserts.assert_true(
1141 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001142 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001143 "Hotspot Allowed List doesn't match")
1144 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1145 asserts.assert_true(
1146 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001147 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001148 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001149
lesl67124362021-05-04 19:33:14 +08001150 if WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY in wifi_config:
1151 asserts.assert_true(
1152 wifi_ap[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY] == wifi_config[
1153 WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY],
1154 "Hotspot Mac randomization setting doesn't match")
1155
1156 if WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY in wifi_config:
1157 asserts.assert_true(
1158 wifi_ap[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY] == wifi_config[
1159 WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY],
1160 "Hotspot bridged shutdown enable setting doesn't match")
1161
1162 if WifiEnums.AP_IEEE80211AX_ENABLED_KEY in wifi_config:
1163 asserts.assert_true(
1164 wifi_ap[WifiEnums.AP_IEEE80211AX_ENABLED_KEY] == wifi_config[
1165 WifiEnums.AP_IEEE80211AX_ENABLED_KEY],
1166 "Hotspot 80211 AX enable setting doesn't match")
1167
1168 if WifiEnums.AP_CHANNEL_FREQUENCYS_KEY in wifi_config:
1169 asserts.assert_true(
1170 wifi_ap[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] == wifi_config[
1171 WifiEnums.AP_CHANNEL_FREQUENCYS_KEY],
1172 "Hotspot channels setting doesn't match")
Omar El Ayach8c017902020-10-18 10:26:57 -07001173
Girish Moturu528b5442018-06-07 10:48:14 -07001174def start_wifi_tethering_saved_config(ad):
1175 """ Turn on wifi hotspot with a config that is already saved """
1176 ad.droid.wifiStartTrackingTetherStateChange()
1177 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1178 try:
1179 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1180 ad.ed.wait_for_event("TetherStateChanged",
1181 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1182 except:
1183 asserts.fail("Didn't receive wifi tethering starting confirmation")
1184 finally:
1185 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001186
Bindu Mahadevff295782019-02-08 16:17:48 -08001187
Ang Li73697b32015-12-03 00:41:53 +00001188def stop_wifi_tethering(ad):
1189 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001190 Args:
1191 ad: android_device to stop wifi tethering on.
1192 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001193 ad.droid.wifiStartTrackingTetherStateChange()
1194 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001195 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001196 ad.ed.pop_event("WifiManagerApDisabled", 30)
1197 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001198 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001199 except Empty:
1200 msg = "Failed to receive confirmation of wifi tethering stopping"
1201 asserts.fail(msg)
1202 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001203 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001204
Ang Li76216d12016-09-20 14:51:57 -07001205
Roshan Pius58916a32016-06-16 16:26:44 -07001206def toggle_wifi_and_wait_for_reconnection(ad,
1207 network,
1208 num_of_tries=1,
1209 assert_on_fail=True):
1210 """Toggle wifi state and then wait for Android device to reconnect to
1211 the provided wifi network.
1212
1213 This expects the device to be already connected to the provided network.
1214
1215 Logic steps are
1216 1. Ensure that we're connected to the network.
1217 2. Turn wifi off.
1218 3. Wait for 10 seconds.
1219 4. Turn wifi on.
1220 5. Wait for the "connected" event, then confirm the connected ssid is the
1221 one requested.
1222
1223 Args:
1224 ad: android_device object to initiate connection on.
1225 network: A dictionary representing the network to await connection. The
1226 dictionary must have the key "SSID".
1227 num_of_tries: An integer that is the number of times to try before
1228 delaring failure. Default is 1.
1229 assert_on_fail: If True, error checks in this function will raise test
1230 failure signals.
1231
1232 Returns:
1233 If assert_on_fail is False, function returns True if the toggle was
1234 successful, False otherwise. If assert_on_fail is True, no return value.
1235 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001236 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1237 assert_on_fail,
1238 ad,
1239 network,
1240 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001241
1242
Girish Moturu5d9f4202019-12-03 15:29:21 -08001243def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001244 """Toggle wifi state and then wait for Android device to reconnect to
1245 the provided wifi network.
1246
1247 This expects the device to be already connected to the provided network.
1248
1249 Logic steps are
1250 1. Ensure that we're connected to the network.
1251 2. Turn wifi off.
1252 3. Wait for 10 seconds.
1253 4. Turn wifi on.
1254 5. Wait for the "connected" event, then confirm the connected ssid is the
1255 one requested.
1256
1257 This will directly fail a test if anything goes wrong.
1258
1259 Args:
1260 ad: android_device object to initiate connection on.
1261 network: A dictionary representing the network to await connection. The
1262 dictionary must have the key "SSID".
1263 num_of_tries: An integer that is the number of times to try before
1264 delaring failure. Default is 1.
1265 """
Roshan Pius58916a32016-06-16 16:26:44 -07001266 expected_ssid = network[WifiEnums.SSID_KEY]
1267 # First ensure that we're already connected to the provided network.
1268 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1269 verify_wifi_connection_info(ad, verify_con)
1270 # Now toggle wifi state and wait for the connection event.
1271 wifi_toggle_state(ad, False)
1272 time.sleep(10)
1273 wifi_toggle_state(ad, True)
1274 ad.droid.wifiStartTrackingStateChange()
1275 try:
1276 connect_result = None
1277 for i in range(num_of_tries):
1278 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001279 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001280 30)
1281 break
1282 except Empty:
1283 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001284 asserts.assert_true(
1285 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1286 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001287 logging.debug("Connection result on %s: %s.", ad.serial,
1288 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001289 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001290 asserts.assert_equal(
1291 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1292 "Expected %s, but got %s." %
1293 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001294 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1295 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001296 finally:
1297 ad.droid.wifiStopTrackingStateChange()
1298
1299
Omar El Ayach8c017902020-10-18 10:26:57 -07001300def wait_for_connect(ad,
1301 expected_ssid=None,
1302 expected_id=None,
1303 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001304 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001305 """Wait for a connect event.
1306
1307 This will directly fail a test if anything goes wrong.
1308
1309 Args:
1310 ad: An Android device object.
1311 expected_ssid: SSID of the network to connect to.
1312 expected_id: Network Id of the network to connect to.
1313 tries: An integer that is the number of times to try before failing.
1314 assert_on_fail: If True, error checks in this function will raise test
1315 failure signals.
1316
1317 Returns:
1318 Returns a value only if assert_on_fail is false.
1319 Returns True if the connection was successful, False otherwise.
1320 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001321 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1322 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001323
1324
Oscar Shucb9af9b2019-05-02 20:01:49 +00001325def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001326 """Wait for a connect event.
1327
1328 Args:
1329 ad: An Android device object.
1330 expected_ssid: SSID of the network to connect to.
1331 expected_id: Network Id of the network to connect to.
1332 tries: An integer that is the number of times to try before failing.
1333 """
1334 ad.droid.wifiStartTrackingStateChange()
1335 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001336 connect_result = _wait_for_connect_event(ad,
1337 ssid=expected_ssid,
1338 id=expected_id,
1339 tries=tries)
1340 asserts.assert_true(
1341 connect_result,
1342 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001343 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1344 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1345 if expected_ssid:
1346 asserts.assert_equal(actual_ssid, expected_ssid,
1347 "Connected to the wrong network")
1348 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1349 if expected_id:
1350 asserts.assert_equal(actual_id, expected_id,
1351 "Connected to the wrong network")
1352 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1353 except Empty:
1354 asserts.fail("Failed to start connection process to %s" %
1355 expected_ssid)
1356 except Exception as error:
1357 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1358 error)
1359 raise signals.TestFailure("Failed to connect to %s network" %
1360 expected_ssid)
1361 finally:
1362 ad.droid.wifiStopTrackingStateChange()
1363
1364
Oscar Shucb9af9b2019-05-02 20:01:49 +00001365def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001366 """Wait for a connect event on queue and pop when available.
1367
1368 Args:
1369 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001370 ssid: SSID of the network to connect to.
1371 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001372 tries: An integer that is the number of times to try before failing.
1373
1374 Returns:
1375 A dict with details of the connection data, which looks like this:
1376 {
1377 'time': 1485460337798,
1378 'name': 'WifiNetworkConnected',
1379 'data': {
1380 'rssi': -27,
1381 'is_24ghz': True,
1382 'mac_address': '02:00:00:00:00:00',
1383 'network_id': 1,
1384 'BSSID': '30:b5:c2:33:d3:fc',
1385 'ip_address': 117483712,
1386 'link_speed': 54,
1387 'supplicant_state': 'completed',
1388 'hidden_ssid': False,
1389 'SSID': 'wh_ap1_2g',
1390 'is_5ghz': False}
1391 }
1392
1393 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001394 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001395
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001396 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001397 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001398 for i in range(tries):
1399 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001400 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1401 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001402 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001403 except Empty:
1404 pass
1405 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001406 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001407 for i in range(tries):
1408 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001409 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1410 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001411 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1412 break
1413 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1414 break
1415 except Empty:
1416 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001417
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001418 return conn_result
1419
Bindu Mahadevff295782019-02-08 16:17:48 -08001420
Roshan Piusffc29912019-01-18 13:39:49 -08001421def wait_for_disconnect(ad, timeout=10):
1422 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001423
1424 Args:
1425 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001426 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001427
1428 """
1429 try:
1430 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001431 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001432 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001433 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001434 finally:
1435 ad.droid.wifiStopTrackingStateChange()
1436
1437
1438def ensure_no_disconnect(ad, duration=10):
1439 """Ensure that there is no disconnect for the specified duration.
1440
1441 Args:
1442 ad: Android device object.
1443 duration: Duration in seconds.
1444
1445 """
1446 try:
1447 ad.droid.wifiStartTrackingStateChange()
1448 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1449 raise signals.TestFailure("Device disconnected from the network")
1450 except Empty:
1451 pass
1452 finally:
1453 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001454
1455
jerrypcchen5cc385d2021-03-11 11:57:21 +00001456def connect_to_wifi_network(ad, network, assert_on_fail=True,
1457 check_connectivity=True, hidden=False,
1458 num_of_scan_tries=3, num_of_connect_tries=3):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001459 """Connection logic for open and psk wifi networks.
1460
1461 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001462 ad: AndroidDevice to use for connection
1463 network: network info of the network to connect to
1464 assert_on_fail: If true, errors from wifi_connect will raise
1465 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001466 hidden: Is the Wifi network hidden.
jerrypcchen5cc385d2021-03-11 11:57:21 +00001467 num_of_scan_tries: The number of times to try scan
1468 interface before declaring failure.
1469 num_of_connect_tries: The number of times to try
1470 connect wifi before declaring failure.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001471 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001472 if hidden:
1473 start_wifi_connection_scan_and_ensure_network_not_found(
jerrypcchen5cc385d2021-03-11 11:57:21 +00001474 ad, network[WifiEnums.SSID_KEY], max_tries=num_of_scan_tries)
Joe Brennan48c3f692019-04-11 08:30:16 -07001475 else:
1476 start_wifi_connection_scan_and_ensure_network_found(
jerrypcchen5cc385d2021-03-11 11:57:21 +00001477 ad, network[WifiEnums.SSID_KEY], max_tries=num_of_scan_tries)
Jong Wook Kim92356922018-02-06 18:32:49 -08001478 wifi_connect(ad,
1479 network,
jerrypcchen5cc385d2021-03-11 11:57:21 +00001480 num_of_tries=num_of_connect_tries,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001481 assert_on_fail=assert_on_fail,
1482 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001483
1484
1485def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1486 """Connect to the given network using network id and verify SSID.
1487
1488 Args:
1489 network_id: int Network Id of the network.
1490 network_ssid: string SSID of the network.
1491
1492 Returns: True if connect using network id was successful;
1493 False otherwise.
1494
1495 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001496 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001497 wifi_connect_by_id(ad, network_id)
1498 connect_data = ad.droid.wifiGetConnectionInfo()
1499 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1500 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001501 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001502 if connect_ssid != network_ssid:
1503 return False
1504 return True
1505
1506
Omar El Ayach8c017902020-10-18 10:26:57 -07001507def wifi_connect(ad,
1508 network,
1509 num_of_tries=1,
1510 assert_on_fail=True,
1511 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001512 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001513
1514 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001515 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001516
Ang Li82522812016-06-02 13:57:21 -07001517 This will directly fail a test if anything goes wrong.
1518
Ang Li73697b32015-12-03 00:41:53 +00001519 Args:
1520 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001521 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001522 dictionary must have the key "SSID".
1523 num_of_tries: An integer that is the number of times to try before
1524 delaring failure. Default is 1.
1525 assert_on_fail: If True, error checks in this function will raise test
1526 failure signals.
1527
1528 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001529 Returns a value only if assert_on_fail is false.
1530 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001531 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001532 return _assert_on_fail_handler(_wifi_connect,
1533 assert_on_fail,
1534 ad,
1535 network,
1536 num_of_tries=num_of_tries,
1537 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001538
1539
Oscar Shucb9af9b2019-05-02 20:01:49 +00001540def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001541 """Connect an Android device to a wifi network.
1542
1543 Initiate connection to a wifi network, wait for the "connected" event, then
1544 confirm the connected ssid is the one requested.
1545
1546 This will directly fail a test if anything goes wrong.
1547
1548 Args:
1549 ad: android_device object to initiate connection on.
1550 network: A dictionary representing the network to connect to. The
1551 dictionary must have the key "SSID".
1552 num_of_tries: An integer that is the number of times to try before
1553 delaring failure. Default is 1.
1554 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001555 asserts.assert_true(
1556 WifiEnums.SSID_KEY in network,
1557 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001558 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001559 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001560 ad.droid.wifiConnectByConfig(network)
1561 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001562 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001563 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001564 connect_result = _wait_for_connect_event(ad,
1565 ssid=expected_ssid,
1566 tries=num_of_tries)
1567 asserts.assert_true(
1568 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1569 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001570 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001571 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001572 asserts.assert_equal(
1573 actual_ssid, expected_ssid,
1574 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001575 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001576
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001577 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001578 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001579 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001580 raise signals.TestFailure(
1581 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001582 except Empty:
1583 asserts.fail("Failed to start connection process to %s on %s" %
1584 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001585 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001586 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1587 error)
1588 raise signals.TestFailure("Failed to connect to %s network" % network)
1589
Ang Li73697b32015-12-03 00:41:53 +00001590 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001591 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001592
Bindu Mahadev50374df2017-01-04 11:03:32 -08001593
Oscar Shucb9af9b2019-05-02 20:01:49 +00001594def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001595 """Connect an Android device to a wifi network using network Id.
1596
1597 Start connection to the wifi network, with the given network Id, wait for
1598 the "connected" event, then verify the connected network is the one requested.
1599
1600 This will directly fail a test if anything goes wrong.
1601
1602 Args:
1603 ad: android_device object to initiate connection on.
1604 network_id: Integer specifying the network id of the network.
1605 num_of_tries: An integer that is the number of times to try before
1606 delaring failure. Default is 1.
1607 assert_on_fail: If True, error checks in this function will raise test
1608 failure signals.
1609
1610 Returns:
1611 Returns a value only if assert_on_fail is false.
1612 Returns True if the connection was successful, False otherwise.
1613 """
1614 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001615 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001616
1617
Oscar Shucb9af9b2019-05-02 20:01:49 +00001618def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001619 """Connect an Android device to a wifi network using it's network id.
1620
1621 Start connection to the wifi network, with the given network id, wait for
1622 the "connected" event, then verify the connected network is the one requested.
1623
1624 Args:
1625 ad: android_device object to initiate connection on.
1626 network_id: Integer specifying the network id of the network.
1627 num_of_tries: An integer that is the number of times to try before
1628 delaring failure. Default is 1.
1629 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001630 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001631 # Clear all previous events.
1632 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001633 ad.droid.wifiConnectByNetworkId(network_id)
1634 ad.log.info("Starting connection to network with id %d", network_id)
1635 try:
1636 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001637 connect_result = _wait_for_connect_event(ad,
1638 id=network_id,
1639 tries=num_of_tries)
1640 asserts.assert_true(
1641 connect_result,
1642 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001643 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1644 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001645 asserts.assert_equal(
1646 actual_id, network_id, "Connected to the wrong network on %s."
1647 "Expected network id = %d, but got %d." %
1648 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001649 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1650 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001651 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001652
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001653 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1654 if not internet:
1655 raise signals.TestFailure("Failed to connect to internet on %s" %
1656 expected_ssid)
1657 except Empty:
1658 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001659 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001660 except Exception as error:
1661 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001662 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001663 raise signals.TestFailure("Failed to connect to network with network"
1664 " id %d" % network_id)
1665 finally:
1666 ad.droid.wifiStopTrackingStateChange()
1667
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001668
Omar El Ayach8c017902020-10-18 10:26:57 -07001669def wifi_connect_using_network_request(ad,
1670 network,
1671 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001672 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001673 """Connect an Android device to a wifi network using network request.
1674
1675 Trigger a network request with the provided network specifier,
1676 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1677 event contain the specified network, then simulate the user granting the
1678 request with the specified network selected. Then wait for the "onAvailable"
1679 network callback indicating successful connection to network.
1680
1681 Args:
1682 ad: android_device object to initiate connection on.
1683 network_specifier: A dictionary representing the network specifier to
1684 use.
1685 network: A dictionary representing the network to connect to. The
1686 dictionary must have the key "SSID".
1687 num_of_tries: An integer that is the number of times to try before
1688 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001689 Returns:
1690 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001691 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001692 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1693 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001694 # Need a delay here because UI interaction should only start once wifi
1695 # starts processing the request.
1696 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001697 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1698 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001699
1700
Omar El Ayach8c017902020-10-18 10:26:57 -07001701def wait_for_wifi_connect_after_network_request(ad,
1702 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001703 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001704 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001705 assert_on_fail=True):
1706 """
1707 Simulate and verify the connection flow after initiating the network
1708 request.
1709
1710 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1711 event contain the specified network, then simulate the user granting the
1712 request with the specified network selected. Then wait for the "onAvailable"
1713 network callback indicating successful connection to network.
1714
1715 Args:
1716 ad: android_device object to initiate connection on.
1717 network: A dictionary representing the network to connect to. The
1718 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001719 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001720 num_of_tries: An integer that is the number of times to try before
1721 delaring failure.
1722 assert_on_fail: If True, error checks in this function will raise test
1723 failure signals.
1724
1725 Returns:
1726 Returns a value only if assert_on_fail is false.
1727 Returns True if the connection was successful, False otherwise.
1728 """
1729 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001730 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001731
1732
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001733def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001734 """
1735 Simulate and verify the connection flow after initiating the network
1736 request.
1737
1738 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1739 event contain the specified network, then simulate the user granting the
1740 request with the specified network selected. Then wait for the "onAvailable"
1741 network callback indicating successful connection to network.
1742
1743 Args:
1744 ad: android_device object to initiate connection on.
1745 network: A dictionary representing the network to connect to. The
1746 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001747 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001748 num_of_tries: An integer that is the number of times to try before
1749 delaring failure.
1750 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001751 asserts.assert_true(
1752 WifiEnums.SSID_KEY in network,
1753 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001754 ad.droid.wifiStartTrackingStateChange()
1755 expected_ssid = network[WifiEnums.SSID_KEY]
1756 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1757 # Wait for the platform to scan and return a list of networks
1758 # matching the request
1759 try:
1760 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001761 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001762 on_match_event = ad.ed.pop_event(
1763 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1764 asserts.assert_true(on_match_event,
1765 "Network request on match not received.")
1766 matched_scan_results = on_match_event["data"]
1767 ad.log.debug("Network request on match results %s",
1768 matched_scan_results)
1769 matched_network = match_networks(
1770 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1771 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001772 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001773 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001774 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001775
Omar El Ayach8c017902020-10-18 10:26:57 -07001776 asserts.assert_true(matched_network,
1777 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001778
1779 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1780 ad.log.info("Sent user selection for network request %s",
1781 expected_ssid)
1782
1783 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001784 autils.wait_for_event_with_keys(
1785 ad, cconsts.EVENT_NETWORK_CALLBACK,
1786 60,
1787 (cconsts.NETWORK_CB_KEY_ID, key),
1788 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1789 on_capabilities_changed = autils.wait_for_event_with_keys(
1790 ad, cconsts.EVENT_NETWORK_CALLBACK,
1791 10,
1792 (cconsts.NETWORK_CB_KEY_ID, key),
1793 (cconsts.NETWORK_CB_KEY_EVENT,
1794 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001795 connected_network = None
1796 # WifiInfo is attached to TransportInfo only in S.
1797 if ad.droid.isSdkAtLeastS():
1798 connected_network = (
1799 on_capabilities_changed["data"][
1800 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1801 )
1802 else:
1803 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001804 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001805 asserts.assert_equal(
1806 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1807 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001808 "Expected %s, but got %s."
1809 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001810 except Empty:
1811 asserts.fail("Failed to connect to %s" % expected_ssid)
1812 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001813 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001814 (expected_ssid, error))
1815 raise signals.TestFailure("Failed to connect to %s network" % network)
1816 finally:
1817 ad.droid.wifiStopTrackingStateChange()
1818
1819
Omar El Ayach8c017902020-10-18 10:26:57 -07001820def wifi_passpoint_connect(ad,
1821 passpoint_network,
1822 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001823 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001824 """Connect an Android device to a wifi network.
1825
1826 Initiate connection to a wifi network, wait for the "connected" event, then
1827 confirm the connected ssid is the one requested.
1828
1829 This will directly fail a test if anything goes wrong.
1830
1831 Args:
1832 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001833 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001834 num_of_tries: An integer that is the number of times to try before
1835 delaring failure. Default is 1.
1836 assert_on_fail: If True, error checks in this function will raise test
1837 failure signals.
1838
1839 Returns:
1840 If assert_on_fail is False, function returns network id, if the connect was
1841 successful, False otherwise. If assert_on_fail is True, no return value.
1842 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001843 _assert_on_fail_handler(_wifi_passpoint_connect,
1844 assert_on_fail,
1845 ad,
1846 passpoint_network,
1847 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001848
1849
Oscar Shucb9af9b2019-05-02 20:01:49 +00001850def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001851 """Connect an Android device to a wifi network.
1852
1853 Initiate connection to a wifi network, wait for the "connected" event, then
1854 confirm the connected ssid is the one requested.
1855
1856 This will directly fail a test if anything goes wrong.
1857
1858 Args:
1859 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001860 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001861 num_of_tries: An integer that is the number of times to try before
1862 delaring failure. Default is 1.
1863 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001864 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001865 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001866 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1867
1868 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001869 connect_result = _wait_for_connect_event(ad, expected_ssid,
1870 num_of_tries)
1871 asserts.assert_true(
1872 connect_result, "Failed to connect to WiFi passpoint network %s on"
1873 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001874 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1875 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001876 asserts.assert_equal(
1877 actual_ssid, expected_ssid,
1878 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001879 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1880
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001881 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1882 if not internet:
1883 raise signals.TestFailure("Failed to connect to internet on %s" %
1884 expected_ssid)
1885 except Exception as error:
1886 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001887 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001888 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001889 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001890
1891 finally:
1892 ad.droid.wifiStopTrackingStateChange()
1893
1894
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001895def delete_passpoint(ad, fqdn):
1896 """Delete a required Passpoint configuration."""
1897 try:
1898 ad.droid.removePasspointConfig(fqdn)
1899 return True
1900 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001901 ad.log.error(
1902 "Failed to remove passpoint configuration with FQDN=%s "
1903 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001904 return False
1905
1906
Ang Li73697b32015-12-03 00:41:53 +00001907def start_wifi_single_scan(ad, scan_setting):
1908 """Starts wifi single shot scan.
1909
1910 Args:
1911 ad: android_device object to initiate connection on.
1912 scan_setting: A dict representing the settings of the scan.
1913
1914 Returns:
1915 If scan was started successfully, event data of success event is returned.
1916 """
Ang Li82522812016-06-02 13:57:21 -07001917 idx = ad.droid.wifiScannerStartScan(scan_setting)
1918 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001919 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001920 return event['data']
1921
Ang Li82522812016-06-02 13:57:21 -07001922
Ang Li73697b32015-12-03 00:41:53 +00001923def track_connection(ad, network_ssid, check_connection_count):
1924 """Track wifi connection to network changes for given number of counts
1925
1926 Args:
1927 ad: android_device object for forget network.
1928 network_ssid: network ssid to which connection would be tracked
1929 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001930 check.
Ang Li73697b32015-12-03 00:41:53 +00001931 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001932 True if connection to given network happen, else return False.
1933 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001934 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001935 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001936 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001937 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001938 if (WifiEnums.SSID_KEY in connect_network['data'] and
1939 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1940 return True
Ang Li8e767182015-12-09 17:29:24 -08001941 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001942 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001943 return False
1944
Ang Li82522812016-06-02 13:57:21 -07001945
Ang Li73697b32015-12-03 00:41:53 +00001946def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1947 """Calculate the scan time required based on the band or channels in scan
1948 setting
1949
1950 Args:
1951 wifi_chs: Object of channels supported
1952 scan_setting: scan setting used for start scan
1953 stime_channel: scan time per channel
1954
1955 Returns:
1956 scan_time: time required for completing a scan
1957 scan_channels: channel used for scanning
1958 """
1959 scan_time = 0
1960 scan_channels = []
1961 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001962 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001963 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001964 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001965 scan_time = len(scan_channels) * stime_channel
1966 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001967 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001968 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001969 return scan_time, scan_channels
1970
Ang Li82522812016-06-02 13:57:21 -07001971
Ang Li73697b32015-12-03 00:41:53 +00001972def start_wifi_track_bssid(ad, track_setting):
1973 """Start tracking Bssid for the given settings.
1974
1975 Args:
1976 ad: android_device object.
1977 track_setting: Setting for which the bssid tracking should be started
1978
1979 Returns:
1980 If tracking started successfully, event data of success event is returned.
1981 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001982 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001983 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001984 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001985 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001986 return event['data']
1987
Ang Li82522812016-06-02 13:57:21 -07001988
Ang Li73697b32015-12-03 00:41:53 +00001989def convert_pem_key_to_pkcs8(in_file, out_file):
1990 """Converts the key file generated by us to the format required by
1991 Android using openssl.
1992
1993 The input file must have the extension "pem". The output file must
1994 have the extension "der".
1995
1996 Args:
1997 in_file: The original key file.
1998 out_file: The full path to the converted key file, including
1999 filename.
2000 """
Ang Li82522812016-06-02 13:57:21 -07002001 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07002002 asserts.assert_true(out_file.endswith(".der"),
2003 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00002004 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
2005 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07002006 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00002007
Ang Li82522812016-06-02 13:57:21 -07002008
Omar El Ayach8c017902020-10-18 10:26:57 -07002009def validate_connection(ad,
2010 ping_addr=DEFAULT_PING_ADDR,
2011 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08002012 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00002013 """Validate internet connection by pinging the address provided.
2014
2015 Args:
2016 ad: android_device object.
2017 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07002018 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00002019
2020 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08002021 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00002022 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07002023 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002024 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08002025 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07002026 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002027 break
2028 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08002029 ping = False
2030 try:
2031 ping = ad.droid.httpPing(ping_addr)
2032 ad.log.info("Http ping result: %s.", ping)
2033 except:
2034 pass
2035 if not ping and ping_gateway:
2036 ad.log.info("Http ping failed. Pinging default gateway")
2037 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2038 result = ad.adb.shell("ping -c 6 {}".format(gw))
2039 ad.log.info("Default gateway ping result: %s" % result)
2040 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002041 return ping
2042
Ang Li82522812016-06-02 13:57:21 -07002043
Ang Li73697b32015-12-03 00:41:53 +00002044#TODO(angli): This can only verify if an actual value is exactly the same.
2045# Would be nice to be able to verify an actual value is one of serveral.
2046def verify_wifi_connection_info(ad, expected_con):
2047 """Verifies that the information of the currently connected wifi network is
2048 as expected.
2049
2050 Args:
2051 expected_con: A dict representing expected key-value pairs for wifi
2052 connection. e.g. {"SSID": "test_wifi"}
2053 """
2054 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002055 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002056 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002057 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002058 # Do not verify authentication related fields.
2059 if k == "password":
2060 continue
Ang Li82522812016-06-02 13:57:21 -07002061 msg = "Field %s does not exist in wifi connection info %s." % (
2062 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002063 if k not in current_con:
2064 raise signals.TestFailure(msg)
2065 actual_v = current_con[k]
2066 if k in case_insensitive:
2067 actual_v = actual_v.lower()
2068 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002069 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002070 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002071 if actual_v != expected_v:
2072 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002073
Ang Li82522812016-06-02 13:57:21 -07002074
Omar El Ayach8c017902020-10-18 10:26:57 -07002075def check_autoconnect_to_open_network(
2076 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002077 """Connects to any open WiFI AP
2078 Args:
2079 timeout value in sec to wait for UE to connect to a WiFi AP
2080 Returns:
2081 True if UE connects to WiFi AP (supplicant_state = completed)
2082 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2083 """
2084 if ad.droid.wifiCheckState():
2085 return True
2086 ad.droid.wifiToggleState()
2087 wifi_connection_state = None
2088 timeout = time.time() + conn_timeout
2089 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002090 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2091 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002092 if time.time() > timeout:
2093 ad.log.warning("Failed to connect to WiFi AP")
2094 return False
2095 return True
2096
2097
Ang Li73697b32015-12-03 00:41:53 +00002098def expand_enterprise_config_by_phase2(config):
2099 """Take an enterprise config and generate a list of configs, each with
2100 a different phase2 auth type.
2101
2102 Args:
2103 config: A dict representing enterprise config.
2104
2105 Returns
2106 A list of enterprise configs.
2107 """
2108 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002109 phase2_types = WifiEnums.EapPhase2
2110 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2111 # Skip unsupported phase2 types for PEAP.
2112 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2113 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002114 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002115 if (WifiEnums.Enterprise.FQDN in config
2116 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002117 continue
2118 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002119 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002120 results.append(c)
2121 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002122
2123
Girish Moturub48a13c2017-02-27 11:36:42 -08002124def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002125 """ Generates a test case name based on an EAP configuration.
2126
2127 Args:
2128 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002129 ad object: Redundant but required as the same param is passed
2130 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002131
2132 Returns:
2133 A string representing the name of a generated EAP test case.
2134 """
2135 eap = WifiEnums.Eap
2136 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002137 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002138 name = "test_connect-"
2139 eap_name = ""
2140 for e in eap:
2141 if e.value == config[Ent.EAP]:
2142 eap_name = e.name
2143 break
2144 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2145 eap_name = "PEAP0"
2146 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2147 eap_name = "PEAP1"
2148 name += eap_name
2149 if Ent.PHASE2 in config:
2150 for e in eap_phase2:
2151 if e.value == config[Ent.PHASE2]:
2152 name += "-{}".format(e.name)
2153 break
2154 return name
2155
2156
Ang Li2d3fe982016-06-08 10:00:43 -07002157def group_attenuators(attenuators):
2158 """Groups a list of attenuators into attenuator groups for backward
2159 compatibility reasons.
2160
2161 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2162 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2163 on an AP, so two of them are connected to one AP.
2164
2165 To make the existing scripts work in the new setup, when the script needs
2166 to attenuate one AP, it needs to set attenuation on both attenuators
2167 connected to the same AP.
2168
2169 This function groups attenuators properly so the scripts work in both
2170 legacy and new Wi-Fi setups.
2171
2172 Args:
2173 attenuators: A list of attenuator objects, either two or four in length.
2174
2175 Raises:
2176 signals.TestFailure is raised if the attenuator list does not have two
2177 or four objects.
2178 """
2179 attn0 = attenuator.AttenuatorGroup("AP0")
2180 attn1 = attenuator.AttenuatorGroup("AP1")
2181 # Legacy testbed setup has two attenuation channels.
2182 num_of_attns = len(attenuators)
2183 if num_of_attns == 2:
2184 attn0.add(attenuators[0])
2185 attn1.add(attenuators[1])
2186 elif num_of_attns == 4:
2187 attn0.add(attenuators[0])
2188 attn0.add(attenuators[1])
2189 attn1.add(attenuators[2])
2190 attn1.add(attenuators[3])
2191 else:
2192 asserts.fail(("Either two or four attenuators are required for this "
2193 "test, but found %s") % num_of_attns)
2194 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002195
Bindu Mahadevff295782019-02-08 16:17:48 -08002196
Girish Moturu36348a32019-12-10 08:41:54 -08002197def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002198 """Sets attenuation values on attenuators used in this test.
2199
2200 Args:
2201 attenuator: The attenuator object.
2202 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002203 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002204 """
2205 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2206 try:
2207 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2208 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2209 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2210 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2211 except:
2212 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002213 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002214 raise
2215
Omar El Ayach8c017902020-10-18 10:26:57 -07002216
Girish Moturu36348a32019-12-10 08:41:54 -08002217def set_attns_steps(attenuators,
2218 atten_val_name,
2219 roaming_attn=ROAMING_ATTN,
2220 steps=10,
2221 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002222 """Set attenuation values on attenuators used in this test. It will change
2223 the attenuation values linearly from current value to target value step by
2224 step.
2225
2226 Args:
2227 attenuators: The list of attenuator objects that you want to change
2228 their attenuation value.
2229 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002230 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002231 steps: Number of attenuator changes to reach the target value.
2232 wait_time: Sleep time for each change of attenuator.
2233 """
2234 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002235 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002236 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2237 target_atten = roaming_attn[atten_val_name]
2238 for current_step in range(steps):
2239 progress = (current_step + 1) / steps
2240 for i, attenuator in enumerate(attenuators):
2241 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2242 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2243 time.sleep(wait_time)
2244
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002245
Girish Moturu36348a32019-12-10 08:41:54 -08002246def trigger_roaming_and_validate(dut,
2247 attenuator,
2248 attn_val_name,
2249 expected_con,
2250 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002251 """Sets attenuators to trigger roaming and validate the DUT connected
2252 to the BSSID expected.
2253
2254 Args:
2255 attenuator: The attenuator object.
2256 attn_val_name: Name of the attenuation value pair to use.
2257 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002258 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002259 """
2260 expected_con = {
2261 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2262 WifiEnums.BSSID_KEY: expected_con["bssid"],
2263 }
Girish Moturu36348a32019-12-10 08:41:54 -08002264 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002265
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002266 verify_wifi_connection_info(dut, expected_con)
2267 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2268 logging.info("Roamed to %s successfully", expected_bssid)
2269 if not validate_connection(dut):
2270 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002271 expected_bssid)
2272
Jong Wook Kim92356922018-02-06 18:32:49 -08002273
2274def create_softap_config():
2275 """Create a softap config with random ssid and password."""
2276 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2277 ap_password = utils.rand_ascii_str(8)
2278 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2279 config = {
2280 WifiEnums.SSID_KEY: ap_ssid,
2281 WifiEnums.PWD_KEY: ap_password,
2282 }
2283 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002284
Omar El Ayach8c017902020-10-18 10:26:57 -07002285
Bindu Mahadevff295782019-02-08 16:17:48 -08002286def start_softap_and_verify(ad, band):
2287 """Bring-up softap and verify AP mode and in scan results.
2288
2289 Args:
2290 band: The band to use for softAP.
2291
2292 Returns: dict, the softAP config.
2293
2294 """
lesl2f0fb232019-11-05 16:35:28 +08002295 # Register before start the test.
2296 callbackId = ad.dut.droid.registerSoftApCallback()
2297 # Check softap info value is default
2298 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2299 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2300 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2301
Bindu Mahadevff295782019-02-08 16:17:48 -08002302 config = create_softap_config()
2303 start_wifi_tethering(ad.dut,
2304 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002305 config[WifiEnums.PWD_KEY],
2306 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002307 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002308 "SoftAp is not reported as running")
2309 start_wifi_connection_scan_and_ensure_network_found(
2310 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002311
2312 # Check softap info can get from callback succeed and assert value should be
2313 # valid.
2314 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2315 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2316 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2317 # Unregister callback
2318 ad.dut.droid.unregisterSoftApCallback(callbackId)
2319
Bindu Mahadevff295782019-02-08 16:17:48 -08002320 return config
2321
Omar El Ayach8c017902020-10-18 10:26:57 -07002322
lesle8e3c0a2019-02-22 17:06:04 +08002323def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002324 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002325 """Wait for the number of softap clients to be updated as expected.
2326 Args:
2327 callbackId: Id of the callback associated with registering.
2328 expected_num_of_softap_clients: expected number of softap clients.
2329 """
2330 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002331 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002332 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2333 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002334 clientMacAddresses = clientData[
2335 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2336 asserts.assert_equal(
2337 clientCount, expected_num_of_softap_clients,
2338 "The number of softap clients doesn't match the expected number")
2339 asserts.assert_equal(
2340 len(clientMacAddresses), expected_num_of_softap_clients,
2341 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002342 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002343 asserts.assert_true(checkMacAddress(macAddress),
2344 "An invalid mac address was returned")
2345
James Mattis5a5dd492020-05-14 13:09:43 -07002346
2347def checkMacAddress(input):
2348 """Validate whether a string is a valid mac address or not.
2349
2350 Args:
2351 input: The string to validate.
2352
2353 Returns: True/False, returns true for a valid mac address and false otherwise.
2354 """
2355 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2356 if re.match(macValidationRegex, input.lower()):
2357 return True
2358 return False
lesle8e3c0a2019-02-22 17:06:04 +08002359
Omar El Ayach8c017902020-10-18 10:26:57 -07002360
lesle8e3c0a2019-02-22 17:06:04 +08002361def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2362 """Wait for the expected softap state change.
2363 Args:
2364 callbackId: Id of the callback associated with registering.
2365 expected_softap_state: The expected softap state.
2366 """
2367 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002368 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2369 asserts.assert_equal(
2370 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2371 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2372 expected_softap_state,
2373 "Softap state doesn't match with expected state")
2374
lesle8e3c0a2019-02-22 17:06:04 +08002375
2376def get_current_number_of_softap_clients(ad, callbackId):
2377 """pop up all of softap client updated event from queue.
2378 Args:
2379 callbackId: Id of the callback associated with registering.
2380
2381 Returns:
2382 If exist aleast callback, returns last updated number_of_softap_clients.
2383 Returns None when no any match callback event in queue.
2384 """
2385 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002386 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002387 events = ad.ed.pop_all(eventStr)
2388 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002389 num_of_clients = event['data'][
2390 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002391 if len(events) == 0:
2392 return None
2393 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002394
Omar El Ayach8c017902020-10-18 10:26:57 -07002395
lesl67124362021-05-04 19:33:14 +08002396def get_current_softap_info(ad, callbackId, need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002397 """pop up all of softap info changed event from queue.
2398 Args:
2399 callbackId: Id of the callback associated with registering.
lesl67124362021-05-04 19:33:14 +08002400 need_to_wait: Wait for the info callback event before pop all.
lesl2f0fb232019-11-05 16:35:28 +08002401 Returns:
2402 Returns last updated information of softap.
2403 """
2404 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002405 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
lesl67124362021-05-04 19:33:14 +08002406 ad.log.debug("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002407 frequency = 0
2408 bandwidth = 0
lesl67124362021-05-04 19:33:14 +08002409 if (need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002410 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002411 frequency = event['data'][
2412 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2413 bandwidth = event['data'][
2414 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002415 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002416 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002417
2418 events = ad.ed.pop_all(eventStr)
2419 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002420 frequency = event['data'][
2421 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2422 bandwidth = event['data'][
2423 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2424 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2425 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002426 return frequency, bandwidth
2427
lesl67124362021-05-04 19:33:14 +08002428def get_current_softap_infos(ad, callbackId, need_to_wait):
2429 """pop up all of softap info list changed event from queue.
2430 Args:
2431 callbackId: Id of the callback associated with registering.
2432 need_to_wait: Wait for the info callback event before pop all.
2433 Returns:
2434 Returns last updated informations of softap.
2435 """
2436 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2437 callbackId) + wifi_constants.SOFTAP_INFOLIST_CHANGED
2438 ad.log.debug("softap info dump from eventStr %s", eventStr)
2439
2440 if (need_to_wait):
2441 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2442 infos = event['data']
2443
2444 events = ad.ed.pop_all(eventStr)
2445 for event in events:
2446 infos = event['data']
2447
2448 for info in infos:
2449 frequency = info[
2450 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2451 bandwidth = info[
2452 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2453 wifistandard = info[
2454 wifi_constants.SOFTAP_INFO_WIFISTANDARD_CALLBACK_KEY]
2455 bssid = info[
2456 wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
2457 ad.log.info(
2458 "softap info, freq:%s, bw:%s, wifistandard:%s, bssid:%s",
2459 frequency, bandwidth, wifistandard, bssid)
2460
2461 return infos
2462
2463def get_current_softap_capability(ad, callbackId, need_to_wait):
2464 """pop up all of softap info list changed event from queue.
2465 Args:
2466 callbackId: Id of the callback associated with registering.
2467 need_to_wait: Wait for the info callback event before pop all.
2468 Returns:
2469 Returns last updated capability of softap.
2470 """
2471 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2472 callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
2473 ad.log.debug("softap capability dump from eventStr %s", eventStr)
2474 if (need_to_wait):
2475 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2476 capability = event['data']
2477
2478 events = ad.ed.pop_all(eventStr)
2479 for event in events:
2480 capability = event['data']
2481
2482 return capability
lesl2f0fb232019-11-05 16:35:28 +08002483
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002484def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002485 """Pulls dumps in the ssrdump dir
2486 Args:
2487 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002488 """
2489 logs = ad.get_file_names("/data/vendor/ssrdump/")
2490 if logs:
2491 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002492 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002493 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002494 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002495 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002496 ignore_status=True)
2497
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002498
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002499def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002500 """Start packet capture in monitor mode.
2501
2502 Args:
2503 pcap: packet capture object
2504 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002505 test_name: test name to be used for pcap file name
2506
2507 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002508 Dictionary with wifi band as key and the tuple
2509 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002510 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002511 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002512 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002513 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002514 if wifi_band == 'dual':
2515 bands = [BAND_2G, BAND_5G]
2516 else:
2517 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002518 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002519 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002520 proc = pcap.start_packet_capture(band, log_dir, test_name)
2521 procs[band] = (proc, os.path.join(log_dir, test_name))
2522 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002523
Bindu Mahadevff295782019-02-08 16:17:48 -08002524
xianyuanjia0431ba32018-12-14 09:56:42 -08002525def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002526 """Stop packet capture in monitor mode.
2527
2528 Since, the pcap logs in monitor mode can be very large, we will
2529 delete them if they are not required. 'test_status' if True, will delete
2530 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002531
2532 Args:
2533 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002534 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002535 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002536 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002537 for proc, fname in procs.values():
2538 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002539
2540 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002541 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002542
Omar El Ayach8c017902020-10-18 10:26:57 -07002543
Jaineel95887fd2019-10-16 16:19:01 -07002544def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002545 """Verify that a mac address is not found in the captured packets.
2546
2547 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002548 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002549 mac: string representation of the mac address
2550 packets: packets obtained by rdpcap(pcap_fname)
2551 """
2552 for pkt in packets:
2553 logging.debug("Packet Summary = %s", pkt.summary())
2554 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002555 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2556 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002557
Omar El Ayach8c017902020-10-18 10:26:57 -07002558
Jaineel95887fd2019-10-16 16:19:01 -07002559def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002560 """Verify that a mac address is found in the captured packets.
2561
2562 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002563 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002564 mac: string representation of the mac address
2565 packets: packets obtained by rdpcap(pcap_fname)
2566 """
2567 for pkt in packets:
2568 if mac in pkt.summary():
2569 return
Jaineel95887fd2019-10-16 16:19:01 -07002570 asserts.fail("Did not find MAC = %s in packet sniffer."
2571 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002572
Omar El Ayach8c017902020-10-18 10:26:57 -07002573
Girish Moturuddc0d382020-08-24 12:08:41 -07002574def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002575 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002576 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002577
Bindu Mahadevff295782019-02-08 16:17:48 -08002578
Girish Moturuddc0d382020-08-24 12:08:41 -07002579def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002580 """Start cnss_diag to record extra wifi logs
2581
2582 Args:
2583 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002584 cnss_diag_file: cnss diag config file to push to device.
2585 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002586 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002587 if ad.model not in pixel_models:
2588 ad.log.info("Device not supported to collect pixel logger")
2589 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002590 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2591 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2592 else:
2593 prop = wifi_constants.CNSS_DIAG_PROP
2594 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002595 if not int(
2596 ad.adb.shell("ls -l %s%s | wc -l" %
2597 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002598 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002599 ad.adb.shell(
2600 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2601 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002602 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2603
Bindu Mahadevff295782019-02-08 16:17:48 -08002604
Girish Moturuddc0d382020-08-24 12:08:41 -07002605def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002606 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002607 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002608
Bindu Mahadevff295782019-02-08 16:17:48 -08002609
Girish Moturuddc0d382020-08-24 12:08:41 -07002610def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002611 """Stops cnss_diag
2612
2613 Args:
2614 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002615 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002616 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002617 if ad.model not in pixel_models:
2618 ad.log.info("Device not supported to collect pixel logger")
2619 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002620 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2621 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2622 else:
2623 prop = wifi_constants.CNSS_DIAG_PROP
2624 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2625
Bindu Mahadevff295782019-02-08 16:17:48 -08002626
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002627def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002628 """Pulls the cnss_diag logs in the wlan_logs dir
2629 Args:
2630 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002631 """
2632 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2633 if logs:
2634 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002635 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002636 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002637 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002638
Bindu Mahadevff295782019-02-08 16:17:48 -08002639
Omar El Ayach8c017902020-10-18 10:26:57 -07002640LinkProbeResult = namedtuple(
2641 'LinkProbeResult',
2642 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002643
2644
2645def send_link_probe(ad):
2646 """Sends a link probe to the currently connected AP, and returns whether the
2647 probe succeeded or not.
2648
2649 Args:
2650 ad: android device object
2651 Returns:
2652 LinkProbeResult namedtuple
2653 """
2654 stdout = ad.adb.shell('cmd wifi send-link-probe')
2655 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2656 'Exception while sending link probe: ' + stdout)
2657
2658 is_success = False
2659 elapsed_time = None
2660 failure_reason = None
2661 if 'succeeded' in stdout:
2662 is_success = True
2663 elapsed_time = next(
2664 (int(token) for token in stdout.split() if token.isdigit()), None)
2665 elif 'failed with reason' in stdout:
2666 failure_reason = next(
2667 (int(token) for token in stdout.split() if token.isdigit()), None)
2668 else:
2669 asserts.fail('Unexpected link probe result: ' + stdout)
2670
Omar El Ayach8c017902020-10-18 10:26:57 -07002671 return LinkProbeResult(is_success=is_success,
2672 stdout=stdout,
2673 elapsed_time=elapsed_time,
2674 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002675
2676
2677def send_link_probes(ad, num_probes, delay_sec):
2678 """Sends a sequence of link probes to the currently connected AP, and
2679 returns whether the probes succeeded or not.
2680
2681 Args:
2682 ad: android device object
2683 num_probes: number of probes to perform
2684 delay_sec: delay time between probes, in seconds
2685 Returns:
2686 List[LinkProbeResult] one LinkProbeResults for each probe
2687 """
2688 logging.info('Sending link probes')
2689 results = []
2690 for _ in range(num_probes):
2691 # send_link_probe() will also fail the test if it sees an exception
2692 # in the stdout of the adb shell command
2693 result = send_link_probe(ad)
2694 logging.info('link probe results: ' + str(result))
2695 results.append(result)
2696 time.sleep(delay_sec)
2697
2698 return results
2699
2700
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002701def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002702 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002703
2704 Args:
2705 test: the calling test class object.
2706 index: int, index of the AP.
2707 ap: access_point object of the AP.
2708 network: dict with information of the network, including ssid,
2709 password and bssid.
2710 bandwidth: the operation bandwidth for the AP, default 80MHz.
2711 channel: the channel number for the AP.
2712 Returns:
2713 brconfigs: the bridge interface configs
2714 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002715 bss_settings = []
2716 ssid = network[WifiEnums.SSID_KEY]
2717 test.access_points[index].close()
2718 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002719
Omar El Ayach8c017902020-10-18 10:26:57 -07002720 # Configure AP as required.
2721 if "password" in network.keys():
2722 password = network["password"]
2723 security = hostapd_security.Security(security_mode="wpa",
2724 password=password)
2725 else:
2726 security = hostapd_security.Security(security_mode=None, password=None)
2727 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2728 ssid=ssid,
2729 security=security,
2730 bss_settings=bss_settings,
2731 vht_bandwidth=bandwidth,
2732 profile_name='whirlwind',
2733 iface_wlan_2g=ap.wlan_2g,
2734 iface_wlan_5g=ap.wlan_5g)
2735 ap.start_ap(config)
2736 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002737
2738
2739def turn_ap_off(test, AP):
2740 """Bring down hostapd on the Access Point.
2741 Args:
2742 test: The test class object.
2743 AP: int, indicating which AP to turn OFF.
2744 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002745 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002746 if hostapd_2g.is_alive():
2747 hostapd_2g.stop()
2748 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002749 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002750 if hostapd_5g.is_alive():
2751 hostapd_5g.stop()
2752 logging.debug('Turned WLAN1 AP%d off' % AP)
2753
2754
2755def turn_ap_on(test, AP):
2756 """Bring up hostapd on the Access Point.
2757 Args:
2758 test: The test class object.
2759 AP: int, indicating which AP to turn ON.
2760 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002761 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002762 if not hostapd_2g.is_alive():
2763 hostapd_2g.start(hostapd_2g.config)
2764 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002765 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002766 if not hostapd_5g.is_alive():
2767 hostapd_5g.start(hostapd_5g.config)
2768 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002769
2770
2771def turn_location_off_and_scan_toggle_off(ad):
2772 """Turns off wifi location scans."""
2773 utils.set_location_service(ad, False)
2774 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2775 msg = "Failed to turn off location service's scan."
2776 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002777
2778
2779def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2780 """ Set SoftAP mode channel
2781
2782 Args:
2783 dut: android device object
2784 ap_iface: interface of SoftAP mode.
2785 cs_count: how many beacon frames before switch channel, default = 10
2786 channel: a wifi channel.
2787 """
2788 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002789 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002790 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002791 chan_switch_result = dut.adb.shell(
2792 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002793 if chan_switch_result == 'OK':
2794 dut.log.info('switch hotspot channel to {}'.format(channel))
2795 return chan_switch_result
2796
2797 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002798
2799def get_wlan0_link(dut):
2800 """ get wlan0 interface status"""
2801 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2802 out = dut.adb.shell(get_wlan0)
2803 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2804 asserts.assert_true("ssid" in out,
2805 "Client doesn't connect to any network")
Alfie Chenb3263dd2021-02-04 18:54:34 +08002806 return out
Girish Moturubea6c7e2021-05-07 16:24:27 -07002807
2808def verify_11ax_wifi_connection(ad, wifi6_supported_models, wifi6_ap):
2809 """Verify 11ax for wifi connection.
2810
2811 Args:
2812 ad: adndroid device object
2813 wifi6_supported_models: device supporting 11ax.
2814 wifi6_ap: if the AP supports 11ax.
2815 """
2816 if wifi6_ap and ad.model in wifi6_supported_models:
2817 logging.info("Verifying 11ax. Model: %s" % ad.model)
2818 asserts.assert_true(
2819 ad.droid.wifiGetConnectionStandard() ==
2820 wifi_constants.WIFI_STANDARD_11AX, "DUT did not connect to 11ax.")
2821
2822def verify_11ax_softap(dut, dut_client, wifi6_supported_models):
2823 """Verify 11ax SoftAp if devices support it.
2824
2825 Check if both DUT and DUT client supports 11ax, then SoftAp turns on
2826 with 11ax mode and DUT client can connect to it.
2827
2828 Args:
2829 dut: Softap device.
2830 dut_client: Client connecting to softap.
2831 wifi6_supported_models: List of device models supporting 11ax.
2832 """
2833 if dut.model in wifi6_supported_models and dut_client.model in wifi6_supported_models:
2834 logging.info(
2835 "Verifying 11ax softap. DUT model: %s, DUT Client model: %s",
2836 dut.model, dut_client.model)
2837 asserts.assert_true(
2838 dut_client.droid.wifiGetConnectionStandard() ==
2839 wifi_constants.WIFI_STANDARD_11AX,
2840 "DUT failed to start SoftAp in 11ax.")
“Alfie90ee7cb2021-04-20 23:16:12 +08002841
2842def check_available_channels_in_bands_2_5(dut, country_code):
2843 """Check if DUT is capable of enable BridgedAp.
2844 #TODO: Find a way to make this function flexible by taking an argument.
2845
2846 Args:
2847 country_code: country code, e.g., 'US', 'JP'.
2848 Returns:
2849 True: If DUT is capable of enable BridgedAp.
2850 False: If DUT is not capable of enable BridgedAp.
2851 """
2852 set_wifi_country_code(dut, country_code)
2853 country = dut.droid.wifiGetCountryCode()
2854 dut.log.info("DUT current country code : {}".format(country))
2855 # Wi-Fi ON and OFF to make sure country code take effet.
2856 wifi_toggle_state(dut, True)
2857 wifi_toggle_state(dut, False)
2858
2859 # Register SoftAp Callback and get SoftAp capability.
2860 callbackId = dut.droid.registerSoftApCallback()
2861 capability = get_current_softap_capability(dut, callbackId, True)
2862 dut.droid.unregisterSoftApCallback(callbackId)
2863
2864 if capability[wifi_constants.
2865 SOFTAP_CAPABILITY_24GHZ_SUPPORTED_CHANNEL_LIST] and \
2866 capability[wifi_constants.
2867 SOFTAP_CAPABILITY_5GHZ_SUPPORTED_CHANNEL_LIST]:
2868 return True
2869 return False
2870
2871
2872@retry(tries=5, delay=2)
2873def validate_ping_between_two_clients(dut1, dut2):
2874 """Make 2 DUT ping each other.
2875
2876 Args:
2877 dut1: An AndroidDevice object.
2878 dut2: An AndroidDevice object.
2879 """
2880 # Get DUTs' IPv4 addresses.
2881 dut1_ip = ""
2882 dut2_ip = ""
2883 try:
2884 dut1_ip = dut1.droid.connectivityGetIPv4Addresses('wlan0')[0]
2885 except IndexError as e:
2886 dut1.log.info(
2887 "{} has no Wi-Fi connection, cannot get IPv4 address."
2888 .format(dut1.serial))
2889 try:
2890 dut2_ip = dut2.droid.connectivityGetIPv4Addresses('wlan0')[0]
2891 except IndexError as e:
2892 dut2.log.info(
2893 "{} has no Wi-Fi connection, cannot get IPv4 address."
2894 .format(dut2.serial))
2895 # Test fail if not able to obtain two DUT's IPv4 addresses.
2896 asserts.assert_true(dut1_ip and dut2_ip,
2897 "Ping failed because no DUT's IPv4 address")
2898
2899 dut1.log.info("{} IPv4 addresses : {}".format(dut1.serial, dut1_ip))
2900 dut2.log.info("{} IPv4 addresses : {}".format(dut2.serial, dut2_ip))
2901
2902 # Two clients ping each other
2903 dut1.log.info("{} ping {}".format(dut1_ip, dut2_ip))
2904 asserts.assert_true(
2905 utils.adb_shell_ping(dut1, count=10, dest_ip=dut2_ip,
2906 timeout=20),
2907 "%s ping %s failed" % (dut1.serial, dut2_ip))
2908
2909 dut2.log.info("{} ping {}".format(dut2_ip, dut1_ip))
2910 asserts.assert_true(
2911 utils.adb_shell_ping(dut2, count=10, dest_ip=dut1_ip,
2912 timeout=20),
2913 "%s ping %s failed" % (dut2.serial, dut1_ip))
2914