blob: 420afb8f0288dc19e0507ea8e0658c1737b8eebe [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
Alfie Chen4c96efe2021-05-21 20:48:54 +0800308 # TODO: add all of the band mapping.
309 softap_band_frequencies = {
310 WIFI_CONFIG_SOFTAP_BAND_2G: ALL_2G_FREQUENCIES,
311 WIFI_CONFIG_SOFTAP_BAND_5G: ALL_5G_FREQUENCIES
312 }
313
Ang Li73697b32015-12-03 00:41:53 +0000314 # All Wifi frequencies to channels lookup.
315 freq_to_channel = {
316 2412: 1,
317 2417: 2,
318 2422: 3,
319 2427: 4,
320 2432: 5,
321 2437: 6,
322 2442: 7,
323 2447: 8,
324 2452: 9,
325 2457: 10,
326 2462: 11,
327 2467: 12,
328 2472: 13,
329 2484: 14,
330 4915: 183,
331 4920: 184,
332 4925: 185,
333 4935: 187,
334 4940: 188,
335 4945: 189,
336 4960: 192,
337 4980: 196,
338 5035: 7,
339 5040: 8,
340 5045: 9,
341 5055: 11,
342 5060: 12,
343 5080: 16,
344 5170: 34,
345 5180: 36,
346 5190: 38,
347 5200: 40,
348 5210: 42,
349 5220: 44,
350 5230: 46,
351 5240: 48,
352 5260: 52,
353 5280: 56,
354 5300: 60,
355 5320: 64,
356 5500: 100,
357 5520: 104,
358 5540: 108,
359 5560: 112,
360 5580: 116,
361 5600: 120,
362 5620: 124,
363 5640: 128,
364 5660: 132,
365 5680: 136,
366 5700: 140,
367 5745: 149,
368 5765: 153,
369 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700370 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000371 5805: 161,
372 5825: 165,
373 }
374
375 # All Wifi channels to frequencies lookup.
376 channel_2G_to_freq = {
377 1: 2412,
378 2: 2417,
379 3: 2422,
380 4: 2427,
381 5: 2432,
382 6: 2437,
383 7: 2442,
384 8: 2447,
385 9: 2452,
386 10: 2457,
387 11: 2462,
388 12: 2467,
389 13: 2472,
390 14: 2484
391 }
392
393 channel_5G_to_freq = {
394 183: 4915,
395 184: 4920,
396 185: 4925,
397 187: 4935,
398 188: 4940,
399 189: 4945,
400 192: 4960,
401 196: 4980,
402 7: 5035,
403 8: 5040,
404 9: 5045,
405 11: 5055,
406 12: 5060,
407 16: 5080,
408 34: 5170,
409 36: 5180,
410 38: 5190,
411 40: 5200,
412 42: 5210,
413 44: 5220,
414 46: 5230,
415 48: 5240,
Omar El Ayach8c017902020-10-18 10:26:57 -0700416 50: 5250,
Ang Li73697b32015-12-03 00:41:53 +0000417 52: 5260,
418 56: 5280,
419 60: 5300,
420 64: 5320,
421 100: 5500,
422 104: 5520,
423 108: 5540,
424 112: 5560,
425 116: 5580,
426 120: 5600,
427 124: 5620,
428 128: 5640,
429 132: 5660,
430 136: 5680,
431 140: 5700,
432 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700433 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000434 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700435 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000436 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700437 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000438 161: 5805,
439 165: 5825
440 }
441
Ang Li82522812016-06-02 13:57:21 -0700442
Ang Li73697b32015-12-03 00:41:53 +0000443class WifiChannelBase:
444 ALL_2G_FREQUENCIES = []
445 DFS_5G_FREQUENCIES = []
446 NONE_DFS_5G_FREQUENCIES = []
447 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
448 MIX_CHANNEL_SCAN = []
449
450 def band_to_freq(self, band):
451 _band_to_frequencies = {
Omar El Ayach8c017902020-10-18 10:26:57 -0700452 WifiEnums.WIFI_BAND_24_GHZ:
453 self.ALL_2G_FREQUENCIES,
454 WifiEnums.WIFI_BAND_5_GHZ:
455 self.NONE_DFS_5G_FREQUENCIES,
456 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY:
457 self.DFS_5G_FREQUENCIES,
458 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS:
459 self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700460 WifiEnums.WIFI_BAND_BOTH:
461 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
462 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
463 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000464 }
465 return _band_to_frequencies[band]
466
Ang Li82522812016-06-02 13:57:21 -0700467
Ang Li73697b32015-12-03 00:41:53 +0000468class WifiChannelUS(WifiChannelBase):
469 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700470 ALL_2G_FREQUENCIES = [
471 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
472 ]
473 NONE_DFS_5G_FREQUENCIES = [
474 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
475 ]
476 MIX_CHANNEL_SCAN = [
477 2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500, 5320, 5520, 5560,
478 5700, 5745, 5805
479 ]
Ang Li73697b32015-12-03 00:41:53 +0000480
“Sandy04280f82021-07-23 17:08:52 +0800481 def __init__(self, model=None, support_addition_channel=[]):
482 if model in support_addition_channel:
483 self.ALL_2G_FREQUENCIES = [
484 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457,
485 2462, 2467, 2472
486 ]
Omar El Ayach8c017902020-10-18 10:26:57 -0700487 self.DFS_5G_FREQUENCIES = [
488 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620,
489 5640, 5660, 5680, 5700, 5720
“Sandy04280f82021-07-23 17:08:52 +0800490 ]
Girish Moturu0c567b02017-08-11 16:20:01 -0700491 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000492
Bindu Mahadevff295782019-02-08 16:17:48 -0800493
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530494class WifiReferenceNetworks:
495 """ Class to parse and return networks of different band and
496 auth type from reference_networks
497 """
498 def __init__(self, obj):
499 self.reference_networks = obj
500 self.WIFI_2G = "2g"
501 self.WIFI_5G = "5g"
502
503 self.secure_networks_2g = []
504 self.secure_networks_5g = []
505 self.open_networks_2g = []
506 self.open_networks_5g = []
507 self._parse_networks()
508
509 def _parse_networks(self):
510 for network in self.reference_networks:
511 for key in network:
512 if key == self.WIFI_2G:
513 if "password" in network[key]:
514 self.secure_networks_2g.append(network[key])
515 else:
516 self.open_networks_2g.append(network[key])
517 else:
518 if "password" in network[key]:
519 self.secure_networks_5g.append(network[key])
520 else:
521 self.open_networks_5g.append(network[key])
522
523 def return_2g_secure_networks(self):
524 return self.secure_networks_2g
525
526 def return_5g_secure_networks(self):
527 return self.secure_networks_5g
528
529 def return_2g_open_networks(self):
530 return self.open_networks_2g
531
532 def return_5g_open_networks(self):
533 return self.open_networks_5g
534
535 def return_secure_networks(self):
536 return self.secure_networks_2g + self.secure_networks_5g
537
538 def return_open_networks(self):
539 return self.open_networks_2g + self.open_networks_5g
540
Ang Li82522812016-06-02 13:57:21 -0700541
542def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
543 """Wrapper function that handles the bahevior of assert_on_fail.
544
545 When assert_on_fail is True, let all test signals through, which can
546 terminate test cases directly. When assert_on_fail is False, the wrapper
547 raises no test signals and reports operation status by returning True or
548 False.
549
550 Args:
551 func: The function to wrap. This function reports operation status by
552 raising test signals.
553 assert_on_fail: A boolean that specifies if the output of the wrapper
554 is test signal based or return value based.
555 args: Positional args for func.
556 kwargs: Name args for func.
557
558 Returns:
559 If assert_on_fail is True, returns True/False to signal operation
560 status, otherwise return nothing.
561 """
562 try:
563 func(*args, **kwargs)
564 if not assert_on_fail:
565 return True
566 except signals.TestSignal:
567 if assert_on_fail:
568 raise
569 return False
570
571
572def assert_network_in_list(target, network_list):
573 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
574 networks.
575
576 Args:
577 target: A dict representing a Wi-Fi network.
578 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
579 network_list: A list of dicts, each representing a Wi-Fi network.
580 """
581 match_results = match_networks(target, network_list)
582 asserts.assert_true(
583 match_results, "Target network %s, does not exist in network list %s" %
584 (target, network_list))
585
586
Ang Li73697b32015-12-03 00:41:53 +0000587def match_networks(target_params, networks):
588 """Finds the WiFi networks that match a given set of parameters in a list
589 of WiFi networks.
590
Girish Moturubc48d9f2016-11-01 13:24:14 -0700591 To be considered a match, the network should contain every key-value pair
592 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000593
594 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700595 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
596 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000597 networks: A list of dict objects representing WiFi networks.
598
599 Returns:
600 The networks that match the target parameters.
601 """
602 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800603 asserts.assert_true(target_params,
604 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000605 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700606 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800607 for k, v in target_params.items():
608 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700609 add_network = 0
610 break
Ang Li9a66de72016-02-08 15:26:38 -0800611 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700612 add_network = 0
613 break
614 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000615 results.append(n)
616 return results
617
Bindu Mahadevff295782019-02-08 16:17:48 -0800618
Roshan Pius93b519c2018-05-09 12:07:11 -0700619def wait_for_wifi_state(ad, state, assert_on_fail=True):
620 """Waits for the device to transition to the specified wifi state
621
622 Args:
623 ad: An AndroidDevice object.
624 state: Wifi state to wait for.
625 assert_on_fail: If True, error checks in this function will raise test
626 failure signals.
627
628 Returns:
629 If assert_on_fail is False, function returns True if the device transitions
630 to the specified state, False otherwise. If assert_on_fail is True, no return value.
631 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700632 return _assert_on_fail_handler(_wait_for_wifi_state,
633 assert_on_fail,
634 ad,
635 state=state)
Roshan Pius93b519c2018-05-09 12:07:11 -0700636
637
638def _wait_for_wifi_state(ad, state):
639 """Toggles the state of wifi.
640
641 TestFailure signals are raised when something goes wrong.
642
643 Args:
644 ad: An AndroidDevice object.
645 state: Wifi state to wait for.
646 """
647 if state == ad.droid.wifiCheckState():
648 # Check if the state is already achieved, so we don't wait for the
649 # state change event by mistake.
650 return
651 ad.droid.wifiStartTrackingStateChange()
Omar El Ayach8c017902020-10-18 10:26:57 -0700652 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (
653 state, ad.serial)
Roshan Pius93b519c2018-05-09 12:07:11 -0700654 try:
655 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
656 lambda x: x["data"]["enabled"] == state,
657 SHORT_TIMEOUT)
658 except Empty:
659 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
660 finally:
661 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700662
Bindu Mahadevff295782019-02-08 16:17:48 -0800663
Ang Li82522812016-06-02 13:57:21 -0700664def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800665 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000666
Ang Li6b557182015-11-11 17:19:17 -0800667 Args:
668 ad: An AndroidDevice object.
669 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700670 assert_on_fail: If True, error checks in this function will raise test
671 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000672
Ang Li6b557182015-11-11 17:19:17 -0800673 Returns:
Ang Li82522812016-06-02 13:57:21 -0700674 If assert_on_fail is False, function returns True if the toggle was
675 successful, False otherwise. If assert_on_fail is True, no return value.
676 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700677 return _assert_on_fail_handler(_wifi_toggle_state,
678 assert_on_fail,
679 ad,
680 new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700681
682
683def _wifi_toggle_state(ad, new_state=None):
684 """Toggles the state of wifi.
685
686 TestFailure signals are raised when something goes wrong.
687
688 Args:
689 ad: An AndroidDevice object.
690 new_state: The state to set Wi-Fi to. If None, opposite of the current
691 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800692 """
Ang Li31b00782016-06-21 13:04:23 -0700693 if new_state is None:
694 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700695 elif new_state == ad.droid.wifiCheckState():
696 # Check if the new_state is already achieved, so we don't wait for the
697 # state change event by mistake.
698 return
699 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700700 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700701 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700702 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800703 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800704 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700705 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
706 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000707 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700708 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
709 lambda x: x["data"]["enabled"] == new_state,
710 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000711 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700712 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800713 finally:
714 ad.droid.wifiStopTrackingStateChange()
715
Ang Li82522812016-06-02 13:57:21 -0700716
Ang Li6b557182015-11-11 17:19:17 -0800717def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700718 """Clears all saved Wi-Fi networks on a device.
719
720 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800721
722 Args:
723 ad: An AndroidDevice object.
724
Ang Li6b557182015-11-11 17:19:17 -0800725 """
Ang Li6b557182015-11-11 17:19:17 -0800726 networks = ad.droid.wifiGetConfiguredNetworks()
727 if not networks:
728 return
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800729 removed = []
Ang Li6b557182015-11-11 17:19:17 -0800730 for n in networks:
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800731 if n['networkId'] not in removed:
732 ad.droid.wifiForgetNetwork(n['networkId'])
733 removed.append(n['networkId'])
734 else:
735 continue
Ang Li6b557182015-11-11 17:19:17 -0800736 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800737 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700738 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800739 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700740 logging.warning("Could not confirm the removal of network %s.", n)
741 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800742 asserts.assert_true(
743 not ad.droid.wifiGetConfiguredNetworks(),
744 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700745
Ang Li73697b32015-12-03 00:41:53 +0000746
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700747def toggle_airplane_mode_on_and_off(ad):
748 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800749
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700750 ad: An AndroidDevice object.
751 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800752
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700753 """
754 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700755 asserts.assert_true(utils.force_airplane_mode(ad, True),
756 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700757 time.sleep(DEFAULT_TIMEOUT)
758 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700759 asserts.assert_true(utils.force_airplane_mode(ad, False),
760 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700761 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800762
763
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700764def toggle_wifi_off_and_on(ad):
765 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800766
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700767 ad: An AndroidDevice object.
768 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800769
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700770 """
771 ad.log.debug("Toggling wifi OFF.")
772 wifi_toggle_state(ad, False)
773 time.sleep(DEFAULT_TIMEOUT)
774 ad.log.debug("Toggling wifi ON.")
775 wifi_toggle_state(ad, True)
776 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800777
778
Ang Li73697b32015-12-03 00:41:53 +0000779def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800780 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000781
Ang Li8e767182015-12-09 17:29:24 -0800782 Args:
783 ad: android_device object for forget network.
784 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000785
Ang Li8e767182015-12-09 17:29:24 -0800786 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700787 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800788 if not networks:
789 return
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800790 removed = []
Ang Li8e767182015-12-09 17:29:24 -0800791 for n in networks:
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800792 if net_ssid in n[WifiEnums.SSID_KEY] and n['networkId'] not in removed:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700793 ad.droid.wifiForgetNetwork(n['networkId'])
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800794 removed.append(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800795 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800796 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800797 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800798 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700799 asserts.fail("Failed to remove network %s." % n)
Jimmy Chen8e40e152021-05-06 14:37:18 +0800800 break
Ang Li73697b32015-12-03 00:41:53 +0000801
Ang Li82522812016-06-02 13:57:21 -0700802
Ang Li73697b32015-12-03 00:41:53 +0000803def wifi_test_device_init(ad):
804 """Initializes an android device for wifi testing.
805
806 0. Make sure SL4A connection is established on the android device.
807 1. Disable location service's WiFi scan.
808 2. Turn WiFi on.
809 3. Clear all saved networks.
810 4. Set country code to US.
811 5. Enable WiFi verbose logging.
812 6. Sync device time with computer time.
813 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700814 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000815 """
Ang Lifee28402016-07-13 13:43:29 -0700816 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000817 ad.droid.wifiScannerToggleAlwaysAvailable(False)
818 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700819 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
820 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800821 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000822 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800823 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700824 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000825 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700826 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700827 output = ad.adb.shell(
828 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
829 "wlan0 log_level EXCESSIVE",
830 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700831 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700832 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800833 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700834 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700835 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000836
Omar El Ayach8c017902020-10-18 10:26:57 -0700837
Roshan Pius48df08c2019-09-13 08:07:30 -0700838def set_wifi_country_code(ad, country_code):
839 """Sets the wifi country code on the device.
840
841 Args:
842 ad: An AndroidDevice object.
843 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800844
845 Raises:
846 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700847 """
Jaineelc5b56a62019-10-10 17:12:02 -0700848 try:
codycaldwell35b87182020-01-16 14:08:01 -0800849 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000850 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700851 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700852
Ang Li82522812016-06-02 13:57:21 -0700853
Ang Li6b557182015-11-11 17:19:17 -0800854def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000855 """Starts a wifi connection scan and wait for results to become available.
856
857 Args:
Ang Li6b557182015-11-11 17:19:17 -0800858 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000859 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800860 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800861 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700862 try:
863 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
864 except Empty:
865 asserts.fail("Wi-Fi results did not become available within 60s.")
866
Ang Li73697b32015-12-03 00:41:53 +0000867
Roshan Piuscb9bc482018-02-01 14:27:09 -0800868def start_wifi_connection_scan_and_return_status(ad):
869 """
870 Starts a wifi connection scan and wait for results to become available
871 or a scan failure to be reported.
872
873 Args:
874 ad: An AndroidDevice object.
875 Returns:
876 True: if scan succeeded & results are available
877 False: if scan failed
878 """
879 ad.ed.clear_all_events()
880 ad.droid.wifiStartScan()
881 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700882 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
883 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800884 except Empty:
885 asserts.fail(
886 "Wi-Fi scan results/failure did not become available within 60s.")
887 # If there are multiple matches, we check for atleast one success.
888 for event in events:
889 if event["name"] == "WifiManagerScanResultsAvailable":
890 return True
891 elif event["name"] == "WifiManagerScanFailure":
892 ad.log.debug("Scan failure received")
893 return False
894
895
Omar El Ayach8c017902020-10-18 10:26:57 -0700896def start_wifi_connection_scan_and_check_for_network(ad,
897 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800898 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800899 """
900 Start connectivity scans & checks if the |network_ssid| is seen in
901 scan results. The method performs a max of |max_tries| connectivity scans
902 to find the network.
903
904 Args:
905 ad: An AndroidDevice object.
906 network_ssid: SSID of the network we are looking for.
907 max_tries: Number of scans to try.
908 Returns:
909 True: if network_ssid is found in scan results.
910 False: if network_ssid is not found in scan results.
911 """
912 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800913 if start_wifi_connection_scan_and_return_status(ad):
914 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700915 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
916 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800917 if len(match_results) > 0:
918 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800919 return False
920
921
Omar El Ayach8c017902020-10-18 10:26:57 -0700922def start_wifi_connection_scan_and_ensure_network_found(
923 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800924 """
925 Start connectivity scans & ensure the |network_ssid| is seen in
926 scan results. The method performs a max of |max_tries| connectivity scans
927 to find the network.
928 This method asserts on failure!
929
930 Args:
931 ad: An AndroidDevice object.
932 network_ssid: SSID of the network we are looking for.
933 max_tries: Number of scans to try.
934 """
935 ad.log.info("Starting scans to ensure %s is present", network_ssid)
936 assert_msg = "Failed to find " + network_ssid + " in scan results" \
937 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700938 asserts.assert_true(
939 start_wifi_connection_scan_and_check_for_network(
940 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800941
942
Omar El Ayach8c017902020-10-18 10:26:57 -0700943def start_wifi_connection_scan_and_ensure_network_not_found(
944 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800945 """
946 Start connectivity scans & ensure the |network_ssid| is not seen in
947 scan results. The method performs a max of |max_tries| connectivity scans
948 to find the network.
949 This method asserts on failure!
950
951 Args:
952 ad: An AndroidDevice object.
953 network_ssid: SSID of the network we are looking for.
954 max_tries: Number of scans to try.
955 """
956 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
957 assert_msg = "Found " + network_ssid + " in scan results" \
958 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700959 asserts.assert_false(
960 start_wifi_connection_scan_and_check_for_network(
961 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800962
963
Ang Li73697b32015-12-03 00:41:53 +0000964def start_wifi_background_scan(ad, scan_setting):
965 """Starts wifi background scan.
966
967 Args:
968 ad: android_device object to initiate connection on.
969 scan_setting: A dict representing the settings of the scan.
970
971 Returns:
972 If scan was started successfully, event data of success event is returned.
973 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700974 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
975 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800976 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000977 return event['data']
978
Ang Li82522812016-06-02 13:57:21 -0700979
Girish Moturu38b993c2021-03-25 13:03:50 -0700980def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
981 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000982 """Starts wifi tethering on an android_device.
983
984 Args:
985 ad: android_device to start wifi tethering on.
986 ssid: The SSID the soft AP should broadcast.
987 password: The password the soft AP should use.
988 band: The band the soft AP should be set on. It should be either
989 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800990 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700991 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000992
993 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700994 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000995 """
Ang Li82522812016-06-02 13:57:21 -0700996 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000997 if password:
998 config[WifiEnums.PWD_KEY] = password
999 if band:
lesl6d30a172020-03-05 15:05:22 +08001000 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -08001001 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -07001002 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -07001003 if security:
1004 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -07001005 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
1006 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -07001007 ad.droid.wifiStartTrackingTetherStateChange()
1008 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001009 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001010 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1011 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001012 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -07001013 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001014 except Empty:
1015 msg = "Failed to receive confirmation of wifi tethering starting"
1016 asserts.fail(msg)
1017 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001018 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001019
Bindu Mahadevff295782019-02-08 16:17:48 -08001020
Omar El Ayach8c017902020-10-18 10:26:57 -07001021def save_wifi_soft_ap_config(ad,
1022 wifi_config,
1023 band=None,
1024 hidden=None,
1025 security=None,
1026 password=None,
1027 channel=None,
1028 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001029 shutdown_timeout_enable=None,
1030 shutdown_timeout_millis=None,
1031 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001032 allowedList=None,
lesl67124362021-05-04 19:33:14 +08001033 blockedList=None,
1034 bands=None,
1035 channel_frequencys=None,
1036 mac_randomization_setting=None,
1037 bridged_opportunistic_shutdown_enabled=None,
1038 ieee80211ax_enabled=None):
lesl6d30a172020-03-05 15:05:22 +08001039 """ Save a soft ap configuration and verified
1040 Args:
1041 ad: android_device to set soft ap configuration.
1042 wifi_config: a soft ap configuration object, at least include SSID.
1043 band: specifies the band for the soft ap.
1044 hidden: specifies the soft ap need to broadcast its SSID or not.
1045 security: specifies the security type for the soft ap.
1046 password: specifies the password for the soft ap.
1047 channel: specifies the channel for the soft ap.
1048 max_clients: specifies the maximum connected client number.
1049 shutdown_timeout_enable: specifies the auto shut down enable or not.
1050 shutdown_timeout_millis: specifies the shut down timeout value.
1051 client_control_enable: specifies the client control enable or not.
1052 allowedList: specifies allowed clients list.
1053 blockedList: specifies blocked clients list.
lesl67124362021-05-04 19:33:14 +08001054 bands: specifies the band list for the soft ap.
1055 channel_frequencys: specifies the channel frequency list for soft ap.
1056 mac_randomization_setting: specifies the mac randomization setting.
1057 bridged_opportunistic_shutdown_enabled: specifies the opportunistic
1058 shutdown enable or not.
1059 ieee80211ax_enabled: specifies the ieee80211ax enable or not.
lesl6d30a172020-03-05 15:05:22 +08001060 """
1061 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001062 wifi_config[WifiEnums.SECURITY] = security
1063 wifi_config[WifiEnums.PWD_KEY] = password
lesl67124362021-05-04 19:33:14 +08001064 if hidden is not None:
Girish Moturu528b5442018-06-07 10:48:14 -07001065 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl67124362021-05-04 19:33:14 +08001066 if max_clients is not None:
lesl6d30a172020-03-05 15:05:22 +08001067 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
lesl67124362021-05-04 19:33:14 +08001068 if shutdown_timeout_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001069 wifi_config[
1070 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
lesl67124362021-05-04 19:33:14 +08001071 if shutdown_timeout_millis is not None:
Omar El Ayach8c017902020-10-18 10:26:57 -07001072 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl67124362021-05-04 19:33:14 +08001073 if client_control_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001074 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
lesl67124362021-05-04 19:33:14 +08001075 if allowedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001076 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
lesl67124362021-05-04 19:33:14 +08001077 if blockedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001078 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
lesl67124362021-05-04 19:33:14 +08001079 if mac_randomization_setting is not None:
1080 wifi_config[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY
1081 ] = mac_randomization_setting
1082 if bridged_opportunistic_shutdown_enabled is not None:
1083 wifi_config[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY
1084 ] = bridged_opportunistic_shutdown_enabled
1085 if ieee80211ax_enabled is not None:
1086 wifi_config[WifiEnums.AP_IEEE80211AX_ENABLED_KEY]= ieee80211ax_enabled
1087 if channel_frequencys is not None:
1088 wifi_config[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] = channel_frequencys
1089 elif bands is not None:
1090 wifi_config[WifiEnums.AP_BANDS_KEY] = bands
1091 elif band is not None:
1092 if channel is not None:
1093 wifi_config[WifiEnums.AP_BAND_KEY] = band
1094 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1095 else:
1096 wifi_config[WifiEnums.AP_BAND_KEY] = band
lesl6d30a172020-03-05 15:05:22 +08001097
1098 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001099 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001100 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1101
1102 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001103 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001104 del wifi_config[WifiEnums.SECURITY]
1105 del wifi_config[WifiEnums.PWD_KEY]
1106
Girish Moturu528b5442018-06-07 10:48:14 -07001107 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1108 "Failed to set WifiAp Configuration")
1109
1110 wifi_ap = ad.droid.wifiGetApConfiguration()
1111 asserts.assert_true(
1112 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001113 "Hotspot SSID doesn't match")
1114 if WifiEnums.SECURITY in wifi_config:
1115 asserts.assert_true(
1116 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1117 "Hotspot Security doesn't match")
1118 if WifiEnums.PWD_KEY in wifi_config:
1119 asserts.assert_true(
1120 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1121 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001122
lesl6d30a172020-03-05 15:05:22 +08001123 if WifiEnums.HIDDEN_KEY in wifi_config:
1124 asserts.assert_true(
1125 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1126 "Hotspot hidden setting doesn't match")
1127
lesl6d30a172020-03-05 15:05:22 +08001128 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1129 asserts.assert_true(
1130 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001131 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001132 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1133 asserts.assert_true(
1134 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001135 WifiEnums.AP_MAXCLIENTS_KEY],
1136 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001137 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1138 asserts.assert_true(
1139 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001140 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001141 "Hotspot ShutDown feature flag doesn't match")
1142 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1143 asserts.assert_true(
1144 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001145 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001146 "Hotspot ShutDown timeout setting doesn't match")
1147 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1148 asserts.assert_true(
1149 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001150 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001151 "Hotspot Client control flag doesn't match")
1152 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1153 asserts.assert_true(
1154 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001155 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001156 "Hotspot Allowed List doesn't match")
1157 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1158 asserts.assert_true(
1159 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001160 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001161 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001162
lesl67124362021-05-04 19:33:14 +08001163 if WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY in wifi_config:
1164 asserts.assert_true(
1165 wifi_ap[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY] == wifi_config[
1166 WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY],
1167 "Hotspot Mac randomization setting doesn't match")
1168
1169 if WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY in wifi_config:
1170 asserts.assert_true(
1171 wifi_ap[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY] == wifi_config[
1172 WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY],
1173 "Hotspot bridged shutdown enable setting doesn't match")
1174
1175 if WifiEnums.AP_IEEE80211AX_ENABLED_KEY in wifi_config:
1176 asserts.assert_true(
1177 wifi_ap[WifiEnums.AP_IEEE80211AX_ENABLED_KEY] == wifi_config[
1178 WifiEnums.AP_IEEE80211AX_ENABLED_KEY],
1179 "Hotspot 80211 AX enable setting doesn't match")
1180
1181 if WifiEnums.AP_CHANNEL_FREQUENCYS_KEY in wifi_config:
1182 asserts.assert_true(
1183 wifi_ap[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] == wifi_config[
1184 WifiEnums.AP_CHANNEL_FREQUENCYS_KEY],
1185 "Hotspot channels setting doesn't match")
Omar El Ayach8c017902020-10-18 10:26:57 -07001186
Girish Moturu528b5442018-06-07 10:48:14 -07001187def start_wifi_tethering_saved_config(ad):
1188 """ Turn on wifi hotspot with a config that is already saved """
1189 ad.droid.wifiStartTrackingTetherStateChange()
1190 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1191 try:
1192 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1193 ad.ed.wait_for_event("TetherStateChanged",
1194 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1195 except:
1196 asserts.fail("Didn't receive wifi tethering starting confirmation")
1197 finally:
1198 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001199
Bindu Mahadevff295782019-02-08 16:17:48 -08001200
Ang Li73697b32015-12-03 00:41:53 +00001201def stop_wifi_tethering(ad):
1202 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001203 Args:
1204 ad: android_device to stop wifi tethering on.
1205 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001206 ad.droid.wifiStartTrackingTetherStateChange()
1207 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001208 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001209 ad.ed.pop_event("WifiManagerApDisabled", 30)
1210 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001211 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001212 except Empty:
1213 msg = "Failed to receive confirmation of wifi tethering stopping"
1214 asserts.fail(msg)
1215 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001216 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001217
Ang Li76216d12016-09-20 14:51:57 -07001218
Roshan Pius58916a32016-06-16 16:26:44 -07001219def toggle_wifi_and_wait_for_reconnection(ad,
1220 network,
1221 num_of_tries=1,
1222 assert_on_fail=True):
1223 """Toggle wifi state and then wait for Android device to reconnect to
1224 the provided wifi network.
1225
1226 This expects the device to be already connected to the provided network.
1227
1228 Logic steps are
1229 1. Ensure that we're connected to the network.
1230 2. Turn wifi off.
1231 3. Wait for 10 seconds.
1232 4. Turn wifi on.
1233 5. Wait for the "connected" event, then confirm the connected ssid is the
1234 one requested.
1235
1236 Args:
1237 ad: android_device object to initiate connection on.
1238 network: A dictionary representing the network to await connection. The
1239 dictionary must have the key "SSID".
1240 num_of_tries: An integer that is the number of times to try before
1241 delaring failure. Default is 1.
1242 assert_on_fail: If True, error checks in this function will raise test
1243 failure signals.
1244
1245 Returns:
1246 If assert_on_fail is False, function returns True if the toggle was
1247 successful, False otherwise. If assert_on_fail is True, no return value.
1248 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001249 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1250 assert_on_fail,
1251 ad,
1252 network,
1253 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001254
1255
Girish Moturu5d9f4202019-12-03 15:29:21 -08001256def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001257 """Toggle wifi state and then wait for Android device to reconnect to
1258 the provided wifi network.
1259
1260 This expects the device to be already connected to the provided network.
1261
1262 Logic steps are
1263 1. Ensure that we're connected to the network.
1264 2. Turn wifi off.
1265 3. Wait for 10 seconds.
1266 4. Turn wifi on.
1267 5. Wait for the "connected" event, then confirm the connected ssid is the
1268 one requested.
1269
1270 This will directly fail a test if anything goes wrong.
1271
1272 Args:
1273 ad: android_device object to initiate connection on.
1274 network: A dictionary representing the network to await connection. The
1275 dictionary must have the key "SSID".
1276 num_of_tries: An integer that is the number of times to try before
1277 delaring failure. Default is 1.
1278 """
Roshan Pius58916a32016-06-16 16:26:44 -07001279 expected_ssid = network[WifiEnums.SSID_KEY]
1280 # First ensure that we're already connected to the provided network.
1281 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1282 verify_wifi_connection_info(ad, verify_con)
1283 # Now toggle wifi state and wait for the connection event.
1284 wifi_toggle_state(ad, False)
1285 time.sleep(10)
1286 wifi_toggle_state(ad, True)
1287 ad.droid.wifiStartTrackingStateChange()
1288 try:
1289 connect_result = None
1290 for i in range(num_of_tries):
1291 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001292 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001293 30)
1294 break
1295 except Empty:
1296 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001297 asserts.assert_true(
1298 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1299 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001300 logging.debug("Connection result on %s: %s.", ad.serial,
1301 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001302 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001303 asserts.assert_equal(
1304 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1305 "Expected %s, but got %s." %
1306 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001307 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1308 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001309 finally:
1310 ad.droid.wifiStopTrackingStateChange()
1311
1312
Omar El Ayach8c017902020-10-18 10:26:57 -07001313def wait_for_connect(ad,
1314 expected_ssid=None,
1315 expected_id=None,
1316 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001317 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001318 """Wait for a connect event.
1319
1320 This will directly fail a test if anything goes wrong.
1321
1322 Args:
1323 ad: An Android device object.
1324 expected_ssid: SSID of the network to connect to.
1325 expected_id: Network Id of the network to connect to.
1326 tries: An integer that is the number of times to try before failing.
1327 assert_on_fail: If True, error checks in this function will raise test
1328 failure signals.
1329
1330 Returns:
1331 Returns a value only if assert_on_fail is false.
1332 Returns True if the connection was successful, False otherwise.
1333 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001334 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1335 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001336
1337
Oscar Shucb9af9b2019-05-02 20:01:49 +00001338def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001339 """Wait for a connect event.
1340
1341 Args:
1342 ad: An Android device object.
1343 expected_ssid: SSID of the network to connect to.
1344 expected_id: Network Id of the network to connect to.
1345 tries: An integer that is the number of times to try before failing.
1346 """
1347 ad.droid.wifiStartTrackingStateChange()
1348 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001349 connect_result = _wait_for_connect_event(ad,
1350 ssid=expected_ssid,
1351 id=expected_id,
1352 tries=tries)
1353 asserts.assert_true(
1354 connect_result,
1355 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001356 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1357 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1358 if expected_ssid:
1359 asserts.assert_equal(actual_ssid, expected_ssid,
1360 "Connected to the wrong network")
1361 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1362 if expected_id:
1363 asserts.assert_equal(actual_id, expected_id,
1364 "Connected to the wrong network")
1365 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1366 except Empty:
1367 asserts.fail("Failed to start connection process to %s" %
1368 expected_ssid)
1369 except Exception as error:
1370 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1371 error)
1372 raise signals.TestFailure("Failed to connect to %s network" %
1373 expected_ssid)
1374 finally:
1375 ad.droid.wifiStopTrackingStateChange()
1376
1377
Oscar Shucb9af9b2019-05-02 20:01:49 +00001378def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001379 """Wait for a connect event on queue and pop when available.
1380
1381 Args:
1382 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001383 ssid: SSID of the network to connect to.
1384 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001385 tries: An integer that is the number of times to try before failing.
1386
1387 Returns:
1388 A dict with details of the connection data, which looks like this:
1389 {
1390 'time': 1485460337798,
1391 'name': 'WifiNetworkConnected',
1392 'data': {
1393 'rssi': -27,
1394 'is_24ghz': True,
1395 'mac_address': '02:00:00:00:00:00',
1396 'network_id': 1,
1397 'BSSID': '30:b5:c2:33:d3:fc',
1398 'ip_address': 117483712,
1399 'link_speed': 54,
1400 'supplicant_state': 'completed',
1401 'hidden_ssid': False,
1402 'SSID': 'wh_ap1_2g',
1403 'is_5ghz': False}
1404 }
1405
1406 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001407 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001408
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001409 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001410 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001411 for i in range(tries):
1412 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001413 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1414 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001415 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001416 except Empty:
1417 pass
1418 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001419 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001420 for i in range(tries):
1421 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001422 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1423 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001424 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1425 break
1426 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1427 break
1428 except Empty:
1429 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001430
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001431 return conn_result
1432
Bindu Mahadevff295782019-02-08 16:17:48 -08001433
Roshan Piusffc29912019-01-18 13:39:49 -08001434def wait_for_disconnect(ad, timeout=10):
1435 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001436
1437 Args:
1438 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001439 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001440
1441 """
1442 try:
1443 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001444 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001445 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001446 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001447 finally:
1448 ad.droid.wifiStopTrackingStateChange()
1449
1450
1451def ensure_no_disconnect(ad, duration=10):
1452 """Ensure that there is no disconnect for the specified duration.
1453
1454 Args:
1455 ad: Android device object.
1456 duration: Duration in seconds.
1457
1458 """
1459 try:
1460 ad.droid.wifiStartTrackingStateChange()
1461 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1462 raise signals.TestFailure("Device disconnected from the network")
1463 except Empty:
1464 pass
1465 finally:
1466 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001467
1468
Omar El Ayach8c017902020-10-18 10:26:57 -07001469def connect_to_wifi_network(ad,
1470 network,
1471 assert_on_fail=True,
1472 check_connectivity=True,
1473 hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001474 """Connection logic for open and psk wifi networks.
1475
1476 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001477 ad: AndroidDevice to use for connection
1478 network: network info of the network to connect to
1479 assert_on_fail: If true, errors from wifi_connect will raise
1480 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001481 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001482 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001483 if hidden:
1484 start_wifi_connection_scan_and_ensure_network_not_found(
1485 ad, network[WifiEnums.SSID_KEY])
1486 else:
1487 start_wifi_connection_scan_and_ensure_network_found(
1488 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001489 wifi_connect(ad,
1490 network,
1491 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001492 assert_on_fail=assert_on_fail,
1493 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001494
1495
1496def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1497 """Connect to the given network using network id and verify SSID.
1498
1499 Args:
1500 network_id: int Network Id of the network.
1501 network_ssid: string SSID of the network.
1502
1503 Returns: True if connect using network id was successful;
1504 False otherwise.
1505
1506 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001507 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001508 wifi_connect_by_id(ad, network_id)
1509 connect_data = ad.droid.wifiGetConnectionInfo()
1510 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1511 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001512 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001513 if connect_ssid != network_ssid:
1514 return False
1515 return True
1516
1517
Omar El Ayach8c017902020-10-18 10:26:57 -07001518def wifi_connect(ad,
1519 network,
1520 num_of_tries=1,
1521 assert_on_fail=True,
1522 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001523 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001524
1525 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001526 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001527
Ang Li82522812016-06-02 13:57:21 -07001528 This will directly fail a test if anything goes wrong.
1529
Ang Li73697b32015-12-03 00:41:53 +00001530 Args:
1531 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001532 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001533 dictionary must have the key "SSID".
1534 num_of_tries: An integer that is the number of times to try before
1535 delaring failure. Default is 1.
1536 assert_on_fail: If True, error checks in this function will raise test
1537 failure signals.
1538
1539 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001540 Returns a value only if assert_on_fail is false.
1541 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001542 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001543 return _assert_on_fail_handler(_wifi_connect,
1544 assert_on_fail,
1545 ad,
1546 network,
1547 num_of_tries=num_of_tries,
1548 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001549
1550
Oscar Shucb9af9b2019-05-02 20:01:49 +00001551def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001552 """Connect an Android device to a wifi network.
1553
1554 Initiate connection to a wifi network, wait for the "connected" event, then
1555 confirm the connected ssid is the one requested.
1556
1557 This will directly fail a test if anything goes wrong.
1558
1559 Args:
1560 ad: android_device object to initiate connection on.
1561 network: A dictionary representing the network to connect to. The
1562 dictionary must have the key "SSID".
1563 num_of_tries: An integer that is the number of times to try before
1564 delaring failure. Default is 1.
1565 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001566 asserts.assert_true(
1567 WifiEnums.SSID_KEY in network,
1568 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001569 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001570 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001571 ad.droid.wifiConnectByConfig(network)
1572 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001573 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001574 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001575 connect_result = _wait_for_connect_event(ad,
1576 ssid=expected_ssid,
1577 tries=num_of_tries)
1578 asserts.assert_true(
1579 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1580 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001581 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001582 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001583 asserts.assert_equal(
1584 actual_ssid, expected_ssid,
1585 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001586 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001587
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001588 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001589 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001590 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001591 raise signals.TestFailure(
1592 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001593 except Empty:
1594 asserts.fail("Failed to start connection process to %s on %s" %
1595 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001596 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001597 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1598 error)
1599 raise signals.TestFailure("Failed to connect to %s network" % network)
1600
Ang Li73697b32015-12-03 00:41:53 +00001601 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001602 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001603
Bindu Mahadev50374df2017-01-04 11:03:32 -08001604
Oscar Shucb9af9b2019-05-02 20:01:49 +00001605def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001606 """Connect an Android device to a wifi network using network Id.
1607
1608 Start connection to the wifi network, with the given network Id, wait for
1609 the "connected" event, then verify the connected network is the one requested.
1610
1611 This will directly fail a test if anything goes wrong.
1612
1613 Args:
1614 ad: android_device object to initiate connection on.
1615 network_id: Integer specifying the network id of the network.
1616 num_of_tries: An integer that is the number of times to try before
1617 delaring failure. Default is 1.
1618 assert_on_fail: If True, error checks in this function will raise test
1619 failure signals.
1620
1621 Returns:
1622 Returns a value only if assert_on_fail is false.
1623 Returns True if the connection was successful, False otherwise.
1624 """
1625 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001626 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001627
1628
Oscar Shucb9af9b2019-05-02 20:01:49 +00001629def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001630 """Connect an Android device to a wifi network using it's network id.
1631
1632 Start connection to the wifi network, with the given network id, wait for
1633 the "connected" event, then verify the connected network is the one requested.
1634
1635 Args:
1636 ad: android_device object to initiate connection on.
1637 network_id: Integer specifying the network id of the network.
1638 num_of_tries: An integer that is the number of times to try before
1639 delaring failure. Default is 1.
1640 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001641 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001642 # Clear all previous events.
1643 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001644 ad.droid.wifiConnectByNetworkId(network_id)
1645 ad.log.info("Starting connection to network with id %d", network_id)
1646 try:
1647 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001648 connect_result = _wait_for_connect_event(ad,
1649 id=network_id,
1650 tries=num_of_tries)
1651 asserts.assert_true(
1652 connect_result,
1653 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001654 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1655 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001656 asserts.assert_equal(
1657 actual_id, network_id, "Connected to the wrong network on %s."
1658 "Expected network id = %d, but got %d." %
1659 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001660 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1661 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001662 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001663
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001664 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1665 if not internet:
1666 raise signals.TestFailure("Failed to connect to internet on %s" %
1667 expected_ssid)
1668 except Empty:
1669 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001670 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001671 except Exception as error:
1672 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001673 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001674 raise signals.TestFailure("Failed to connect to network with network"
1675 " id %d" % network_id)
1676 finally:
1677 ad.droid.wifiStopTrackingStateChange()
1678
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001679
Omar El Ayach8c017902020-10-18 10:26:57 -07001680def wifi_connect_using_network_request(ad,
1681 network,
1682 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001683 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001684 """Connect an Android device to a wifi network using network request.
1685
1686 Trigger a network request with the provided network specifier,
1687 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1688 event contain the specified network, then simulate the user granting the
1689 request with the specified network selected. Then wait for the "onAvailable"
1690 network callback indicating successful connection to network.
1691
1692 Args:
1693 ad: android_device object to initiate connection on.
1694 network_specifier: A dictionary representing the network specifier to
1695 use.
1696 network: A dictionary representing the network to connect to. The
1697 dictionary must have the key "SSID".
1698 num_of_tries: An integer that is the number of times to try before
1699 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001700 Returns:
1701 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001702 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001703 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1704 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001705 # Need a delay here because UI interaction should only start once wifi
1706 # starts processing the request.
1707 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001708 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1709 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001710
1711
Omar El Ayach8c017902020-10-18 10:26:57 -07001712def wait_for_wifi_connect_after_network_request(ad,
1713 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001714 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001715 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001716 assert_on_fail=True):
1717 """
1718 Simulate and verify the connection flow after initiating the network
1719 request.
1720
1721 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1722 event contain the specified network, then simulate the user granting the
1723 request with the specified network selected. Then wait for the "onAvailable"
1724 network callback indicating successful connection to network.
1725
1726 Args:
1727 ad: android_device object to initiate connection on.
1728 network: A dictionary representing the network to connect to. The
1729 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001730 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001731 num_of_tries: An integer that is the number of times to try before
1732 delaring failure.
1733 assert_on_fail: If True, error checks in this function will raise test
1734 failure signals.
1735
1736 Returns:
1737 Returns a value only if assert_on_fail is false.
1738 Returns True if the connection was successful, False otherwise.
1739 """
1740 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001741 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001742
1743
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001744def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001745 """
1746 Simulate and verify the connection flow after initiating the network
1747 request.
1748
1749 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1750 event contain the specified network, then simulate the user granting the
1751 request with the specified network selected. Then wait for the "onAvailable"
1752 network callback indicating successful connection to network.
1753
1754 Args:
1755 ad: android_device object to initiate connection on.
1756 network: A dictionary representing the network to connect to. The
1757 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001758 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001759 num_of_tries: An integer that is the number of times to try before
1760 delaring failure.
1761 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001762 asserts.assert_true(
1763 WifiEnums.SSID_KEY in network,
1764 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001765 ad.droid.wifiStartTrackingStateChange()
1766 expected_ssid = network[WifiEnums.SSID_KEY]
1767 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1768 # Wait for the platform to scan and return a list of networks
1769 # matching the request
1770 try:
1771 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001772 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001773 on_match_event = ad.ed.pop_event(
1774 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1775 asserts.assert_true(on_match_event,
1776 "Network request on match not received.")
1777 matched_scan_results = on_match_event["data"]
1778 ad.log.debug("Network request on match results %s",
1779 matched_scan_results)
1780 matched_network = match_networks(
1781 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1782 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001783 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001784 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001785 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001786
Omar El Ayach8c017902020-10-18 10:26:57 -07001787 asserts.assert_true(matched_network,
1788 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001789
1790 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1791 ad.log.info("Sent user selection for network request %s",
1792 expected_ssid)
1793
1794 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001795 autils.wait_for_event_with_keys(
1796 ad, cconsts.EVENT_NETWORK_CALLBACK,
1797 60,
1798 (cconsts.NETWORK_CB_KEY_ID, key),
1799 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1800 on_capabilities_changed = autils.wait_for_event_with_keys(
1801 ad, cconsts.EVENT_NETWORK_CALLBACK,
1802 10,
1803 (cconsts.NETWORK_CB_KEY_ID, key),
1804 (cconsts.NETWORK_CB_KEY_EVENT,
1805 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001806 connected_network = None
1807 # WifiInfo is attached to TransportInfo only in S.
1808 if ad.droid.isSdkAtLeastS():
1809 connected_network = (
1810 on_capabilities_changed["data"][
1811 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1812 )
1813 else:
1814 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001815 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001816 asserts.assert_equal(
1817 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1818 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001819 "Expected %s, but got %s."
1820 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001821 except Empty:
1822 asserts.fail("Failed to connect to %s" % expected_ssid)
1823 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001824 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001825 (expected_ssid, error))
1826 raise signals.TestFailure("Failed to connect to %s network" % network)
1827 finally:
1828 ad.droid.wifiStopTrackingStateChange()
1829
1830
Omar El Ayach8c017902020-10-18 10:26:57 -07001831def wifi_passpoint_connect(ad,
1832 passpoint_network,
1833 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001834 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001835 """Connect an Android device to a wifi network.
1836
1837 Initiate connection to a wifi network, wait for the "connected" event, then
1838 confirm the connected ssid is the one requested.
1839
1840 This will directly fail a test if anything goes wrong.
1841
1842 Args:
1843 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001844 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001845 num_of_tries: An integer that is the number of times to try before
1846 delaring failure. Default is 1.
1847 assert_on_fail: If True, error checks in this function will raise test
1848 failure signals.
1849
1850 Returns:
1851 If assert_on_fail is False, function returns network id, if the connect was
1852 successful, False otherwise. If assert_on_fail is True, no return value.
1853 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001854 _assert_on_fail_handler(_wifi_passpoint_connect,
1855 assert_on_fail,
1856 ad,
1857 passpoint_network,
1858 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001859
1860
Oscar Shucb9af9b2019-05-02 20:01:49 +00001861def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001862 """Connect an Android device to a wifi network.
1863
1864 Initiate connection to a wifi network, wait for the "connected" event, then
1865 confirm the connected ssid is the one requested.
1866
1867 This will directly fail a test if anything goes wrong.
1868
1869 Args:
1870 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001871 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001872 num_of_tries: An integer that is the number of times to try before
1873 delaring failure. Default is 1.
1874 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001875 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001876 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001877 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1878
1879 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001880 connect_result = _wait_for_connect_event(ad, expected_ssid,
1881 num_of_tries)
1882 asserts.assert_true(
1883 connect_result, "Failed to connect to WiFi passpoint network %s on"
1884 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001885 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1886 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001887 asserts.assert_equal(
1888 actual_ssid, expected_ssid,
1889 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001890 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1891
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001892 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1893 if not internet:
1894 raise signals.TestFailure("Failed to connect to internet on %s" %
1895 expected_ssid)
1896 except Exception as error:
1897 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001898 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001899 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001900 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001901
1902 finally:
1903 ad.droid.wifiStopTrackingStateChange()
1904
1905
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001906def delete_passpoint(ad, fqdn):
1907 """Delete a required Passpoint configuration."""
1908 try:
1909 ad.droid.removePasspointConfig(fqdn)
1910 return True
1911 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001912 ad.log.error(
1913 "Failed to remove passpoint configuration with FQDN=%s "
1914 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001915 return False
1916
1917
Ang Li73697b32015-12-03 00:41:53 +00001918def start_wifi_single_scan(ad, scan_setting):
1919 """Starts wifi single shot scan.
1920
1921 Args:
1922 ad: android_device object to initiate connection on.
1923 scan_setting: A dict representing the settings of the scan.
1924
1925 Returns:
1926 If scan was started successfully, event data of success event is returned.
1927 """
Ang Li82522812016-06-02 13:57:21 -07001928 idx = ad.droid.wifiScannerStartScan(scan_setting)
1929 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001930 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001931 return event['data']
1932
Ang Li82522812016-06-02 13:57:21 -07001933
Ang Li73697b32015-12-03 00:41:53 +00001934def track_connection(ad, network_ssid, check_connection_count):
1935 """Track wifi connection to network changes for given number of counts
1936
1937 Args:
1938 ad: android_device object for forget network.
1939 network_ssid: network ssid to which connection would be tracked
1940 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001941 check.
Ang Li73697b32015-12-03 00:41:53 +00001942 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001943 True if connection to given network happen, else return False.
1944 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001945 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001946 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001947 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001948 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001949 if (WifiEnums.SSID_KEY in connect_network['data'] and
1950 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1951 return True
Ang Li8e767182015-12-09 17:29:24 -08001952 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001953 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001954 return False
1955
Ang Li82522812016-06-02 13:57:21 -07001956
Ang Li73697b32015-12-03 00:41:53 +00001957def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1958 """Calculate the scan time required based on the band or channels in scan
1959 setting
1960
1961 Args:
1962 wifi_chs: Object of channels supported
1963 scan_setting: scan setting used for start scan
1964 stime_channel: scan time per channel
1965
1966 Returns:
1967 scan_time: time required for completing a scan
1968 scan_channels: channel used for scanning
1969 """
1970 scan_time = 0
1971 scan_channels = []
1972 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001973 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001974 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001975 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001976 scan_time = len(scan_channels) * stime_channel
1977 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001978 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001979 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001980 return scan_time, scan_channels
1981
Ang Li82522812016-06-02 13:57:21 -07001982
Ang Li73697b32015-12-03 00:41:53 +00001983def start_wifi_track_bssid(ad, track_setting):
1984 """Start tracking Bssid for the given settings.
1985
1986 Args:
1987 ad: android_device object.
1988 track_setting: Setting for which the bssid tracking should be started
1989
1990 Returns:
1991 If tracking started successfully, event data of success event is returned.
1992 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001993 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001994 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001995 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001996 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001997 return event['data']
1998
Ang Li82522812016-06-02 13:57:21 -07001999
Ang Li73697b32015-12-03 00:41:53 +00002000def convert_pem_key_to_pkcs8(in_file, out_file):
2001 """Converts the key file generated by us to the format required by
2002 Android using openssl.
2003
2004 The input file must have the extension "pem". The output file must
2005 have the extension "der".
2006
2007 Args:
2008 in_file: The original key file.
2009 out_file: The full path to the converted key file, including
2010 filename.
2011 """
Ang Li82522812016-06-02 13:57:21 -07002012 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07002013 asserts.assert_true(out_file.endswith(".der"),
2014 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00002015 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
2016 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07002017 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00002018
Ang Li82522812016-06-02 13:57:21 -07002019
Omar El Ayach8c017902020-10-18 10:26:57 -07002020def validate_connection(ad,
2021 ping_addr=DEFAULT_PING_ADDR,
2022 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08002023 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00002024 """Validate internet connection by pinging the address provided.
2025
2026 Args:
2027 ad: android_device object.
2028 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07002029 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00002030
2031 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08002032 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00002033 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07002034 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002035 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08002036 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07002037 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002038 break
2039 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08002040 ping = False
2041 try:
2042 ping = ad.droid.httpPing(ping_addr)
2043 ad.log.info("Http ping result: %s.", ping)
2044 except:
2045 pass
2046 if not ping and ping_gateway:
2047 ad.log.info("Http ping failed. Pinging default gateway")
2048 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2049 result = ad.adb.shell("ping -c 6 {}".format(gw))
2050 ad.log.info("Default gateway ping result: %s" % result)
2051 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002052 return ping
2053
Ang Li82522812016-06-02 13:57:21 -07002054
Ang Li73697b32015-12-03 00:41:53 +00002055#TODO(angli): This can only verify if an actual value is exactly the same.
2056# Would be nice to be able to verify an actual value is one of serveral.
2057def verify_wifi_connection_info(ad, expected_con):
2058 """Verifies that the information of the currently connected wifi network is
2059 as expected.
2060
2061 Args:
2062 expected_con: A dict representing expected key-value pairs for wifi
2063 connection. e.g. {"SSID": "test_wifi"}
2064 """
2065 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002066 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002067 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002068 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002069 # Do not verify authentication related fields.
2070 if k == "password":
2071 continue
Ang Li82522812016-06-02 13:57:21 -07002072 msg = "Field %s does not exist in wifi connection info %s." % (
2073 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002074 if k not in current_con:
2075 raise signals.TestFailure(msg)
2076 actual_v = current_con[k]
2077 if k in case_insensitive:
2078 actual_v = actual_v.lower()
2079 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002080 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002081 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002082 if actual_v != expected_v:
2083 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002084
Ang Li82522812016-06-02 13:57:21 -07002085
Omar El Ayach8c017902020-10-18 10:26:57 -07002086def check_autoconnect_to_open_network(
2087 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002088 """Connects to any open WiFI AP
2089 Args:
2090 timeout value in sec to wait for UE to connect to a WiFi AP
2091 Returns:
2092 True if UE connects to WiFi AP (supplicant_state = completed)
2093 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2094 """
2095 if ad.droid.wifiCheckState():
2096 return True
2097 ad.droid.wifiToggleState()
2098 wifi_connection_state = None
2099 timeout = time.time() + conn_timeout
2100 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002101 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2102 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002103 if time.time() > timeout:
2104 ad.log.warning("Failed to connect to WiFi AP")
2105 return False
2106 return True
2107
2108
Ang Li73697b32015-12-03 00:41:53 +00002109def expand_enterprise_config_by_phase2(config):
2110 """Take an enterprise config and generate a list of configs, each with
2111 a different phase2 auth type.
2112
2113 Args:
2114 config: A dict representing enterprise config.
2115
2116 Returns
2117 A list of enterprise configs.
2118 """
2119 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002120 phase2_types = WifiEnums.EapPhase2
2121 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2122 # Skip unsupported phase2 types for PEAP.
2123 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2124 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002125 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002126 if (WifiEnums.Enterprise.FQDN in config
2127 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002128 continue
2129 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002130 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002131 results.append(c)
2132 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002133
2134
Girish Moturub48a13c2017-02-27 11:36:42 -08002135def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002136 """ Generates a test case name based on an EAP configuration.
2137
2138 Args:
2139 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002140 ad object: Redundant but required as the same param is passed
2141 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002142
2143 Returns:
2144 A string representing the name of a generated EAP test case.
2145 """
2146 eap = WifiEnums.Eap
2147 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002148 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002149 name = "test_connect-"
2150 eap_name = ""
2151 for e in eap:
2152 if e.value == config[Ent.EAP]:
2153 eap_name = e.name
2154 break
2155 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2156 eap_name = "PEAP0"
2157 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2158 eap_name = "PEAP1"
2159 name += eap_name
2160 if Ent.PHASE2 in config:
2161 for e in eap_phase2:
2162 if e.value == config[Ent.PHASE2]:
2163 name += "-{}".format(e.name)
2164 break
2165 return name
2166
2167
Ang Li2d3fe982016-06-08 10:00:43 -07002168def group_attenuators(attenuators):
2169 """Groups a list of attenuators into attenuator groups for backward
2170 compatibility reasons.
2171
2172 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2173 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2174 on an AP, so two of them are connected to one AP.
2175
2176 To make the existing scripts work in the new setup, when the script needs
2177 to attenuate one AP, it needs to set attenuation on both attenuators
2178 connected to the same AP.
2179
2180 This function groups attenuators properly so the scripts work in both
2181 legacy and new Wi-Fi setups.
2182
2183 Args:
2184 attenuators: A list of attenuator objects, either two or four in length.
2185
2186 Raises:
2187 signals.TestFailure is raised if the attenuator list does not have two
2188 or four objects.
2189 """
2190 attn0 = attenuator.AttenuatorGroup("AP0")
2191 attn1 = attenuator.AttenuatorGroup("AP1")
2192 # Legacy testbed setup has two attenuation channels.
2193 num_of_attns = len(attenuators)
2194 if num_of_attns == 2:
2195 attn0.add(attenuators[0])
2196 attn1.add(attenuators[1])
2197 elif num_of_attns == 4:
2198 attn0.add(attenuators[0])
2199 attn0.add(attenuators[1])
2200 attn1.add(attenuators[2])
2201 attn1.add(attenuators[3])
2202 else:
2203 asserts.fail(("Either two or four attenuators are required for this "
2204 "test, but found %s") % num_of_attns)
2205 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002206
Bindu Mahadevff295782019-02-08 16:17:48 -08002207
Girish Moturu36348a32019-12-10 08:41:54 -08002208def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002209 """Sets attenuation values on attenuators used in this test.
2210
2211 Args:
2212 attenuator: The attenuator object.
2213 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002214 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002215 """
2216 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2217 try:
2218 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2219 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2220 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2221 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2222 except:
2223 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002224 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002225 raise
2226
Omar El Ayach8c017902020-10-18 10:26:57 -07002227
Girish Moturu36348a32019-12-10 08:41:54 -08002228def set_attns_steps(attenuators,
2229 atten_val_name,
2230 roaming_attn=ROAMING_ATTN,
2231 steps=10,
2232 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002233 """Set attenuation values on attenuators used in this test. It will change
2234 the attenuation values linearly from current value to target value step by
2235 step.
2236
2237 Args:
2238 attenuators: The list of attenuator objects that you want to change
2239 their attenuation value.
2240 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002241 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002242 steps: Number of attenuator changes to reach the target value.
2243 wait_time: Sleep time for each change of attenuator.
2244 """
2245 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002246 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002247 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2248 target_atten = roaming_attn[atten_val_name]
2249 for current_step in range(steps):
2250 progress = (current_step + 1) / steps
2251 for i, attenuator in enumerate(attenuators):
2252 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2253 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2254 time.sleep(wait_time)
2255
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002256
Girish Moturu36348a32019-12-10 08:41:54 -08002257def trigger_roaming_and_validate(dut,
2258 attenuator,
2259 attn_val_name,
2260 expected_con,
2261 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002262 """Sets attenuators to trigger roaming and validate the DUT connected
2263 to the BSSID expected.
2264
2265 Args:
2266 attenuator: The attenuator object.
2267 attn_val_name: Name of the attenuation value pair to use.
2268 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002269 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002270 """
2271 expected_con = {
2272 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2273 WifiEnums.BSSID_KEY: expected_con["bssid"],
2274 }
Girish Moturu36348a32019-12-10 08:41:54 -08002275 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002276
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002277 verify_wifi_connection_info(dut, expected_con)
2278 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2279 logging.info("Roamed to %s successfully", expected_bssid)
2280 if not validate_connection(dut):
2281 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002282 expected_bssid)
2283
Jong Wook Kim92356922018-02-06 18:32:49 -08002284
2285def create_softap_config():
2286 """Create a softap config with random ssid and password."""
2287 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2288 ap_password = utils.rand_ascii_str(8)
2289 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2290 config = {
2291 WifiEnums.SSID_KEY: ap_ssid,
2292 WifiEnums.PWD_KEY: ap_password,
2293 }
2294 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002295
Omar El Ayach8c017902020-10-18 10:26:57 -07002296
Bindu Mahadevff295782019-02-08 16:17:48 -08002297def start_softap_and_verify(ad, band):
2298 """Bring-up softap and verify AP mode and in scan results.
2299
2300 Args:
2301 band: The band to use for softAP.
2302
2303 Returns: dict, the softAP config.
2304
2305 """
lesl2f0fb232019-11-05 16:35:28 +08002306 # Register before start the test.
2307 callbackId = ad.dut.droid.registerSoftApCallback()
2308 # Check softap info value is default
2309 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2310 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2311 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2312
Bindu Mahadevff295782019-02-08 16:17:48 -08002313 config = create_softap_config()
2314 start_wifi_tethering(ad.dut,
2315 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002316 config[WifiEnums.PWD_KEY],
2317 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002318 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002319 "SoftAp is not reported as running")
2320 start_wifi_connection_scan_and_ensure_network_found(
2321 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002322
2323 # Check softap info can get from callback succeed and assert value should be
2324 # valid.
2325 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2326 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2327 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2328 # Unregister callback
2329 ad.dut.droid.unregisterSoftApCallback(callbackId)
2330
Bindu Mahadevff295782019-02-08 16:17:48 -08002331 return config
2332
Omar El Ayach8c017902020-10-18 10:26:57 -07002333
lesle8e3c0a2019-02-22 17:06:04 +08002334def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002335 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002336 """Wait for the number of softap clients to be updated as expected.
2337 Args:
2338 callbackId: Id of the callback associated with registering.
2339 expected_num_of_softap_clients: expected number of softap clients.
2340 """
2341 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002342 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002343 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2344 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002345 clientMacAddresses = clientData[
2346 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2347 asserts.assert_equal(
2348 clientCount, expected_num_of_softap_clients,
2349 "The number of softap clients doesn't match the expected number")
2350 asserts.assert_equal(
2351 len(clientMacAddresses), expected_num_of_softap_clients,
2352 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002353 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002354 asserts.assert_true(checkMacAddress(macAddress),
2355 "An invalid mac address was returned")
2356
James Mattis5a5dd492020-05-14 13:09:43 -07002357
2358def checkMacAddress(input):
2359 """Validate whether a string is a valid mac address or not.
2360
2361 Args:
2362 input: The string to validate.
2363
2364 Returns: True/False, returns true for a valid mac address and false otherwise.
2365 """
2366 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2367 if re.match(macValidationRegex, input.lower()):
2368 return True
2369 return False
lesle8e3c0a2019-02-22 17:06:04 +08002370
Omar El Ayach8c017902020-10-18 10:26:57 -07002371
lesle8e3c0a2019-02-22 17:06:04 +08002372def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2373 """Wait for the expected softap state change.
2374 Args:
2375 callbackId: Id of the callback associated with registering.
2376 expected_softap_state: The expected softap state.
2377 """
2378 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002379 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2380 asserts.assert_equal(
2381 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2382 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2383 expected_softap_state,
2384 "Softap state doesn't match with expected state")
2385
lesle8e3c0a2019-02-22 17:06:04 +08002386
2387def get_current_number_of_softap_clients(ad, callbackId):
2388 """pop up all of softap client updated event from queue.
2389 Args:
2390 callbackId: Id of the callback associated with registering.
2391
2392 Returns:
2393 If exist aleast callback, returns last updated number_of_softap_clients.
2394 Returns None when no any match callback event in queue.
2395 """
2396 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002397 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002398 events = ad.ed.pop_all(eventStr)
2399 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002400 num_of_clients = event['data'][
2401 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002402 if len(events) == 0:
2403 return None
2404 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002405
Omar El Ayach8c017902020-10-18 10:26:57 -07002406
lesl67124362021-05-04 19:33:14 +08002407def get_current_softap_info(ad, callbackId, need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002408 """pop up all of softap info changed event from queue.
2409 Args:
2410 callbackId: Id of the callback associated with registering.
lesl67124362021-05-04 19:33:14 +08002411 need_to_wait: Wait for the info callback event before pop all.
lesl2f0fb232019-11-05 16:35:28 +08002412 Returns:
2413 Returns last updated information of softap.
2414 """
2415 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002416 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
lesl67124362021-05-04 19:33:14 +08002417 ad.log.debug("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002418 frequency = 0
2419 bandwidth = 0
lesl67124362021-05-04 19:33:14 +08002420 if (need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002421 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002422 frequency = event['data'][
2423 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2424 bandwidth = event['data'][
2425 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002426 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002427 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002428
2429 events = ad.ed.pop_all(eventStr)
2430 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002431 frequency = event['data'][
2432 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2433 bandwidth = event['data'][
2434 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2435 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2436 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002437 return frequency, bandwidth
2438
lesl67124362021-05-04 19:33:14 +08002439def get_current_softap_infos(ad, callbackId, need_to_wait):
2440 """pop up all of softap info list changed event from queue.
2441 Args:
2442 callbackId: Id of the callback associated with registering.
2443 need_to_wait: Wait for the info callback event before pop all.
2444 Returns:
2445 Returns last updated informations of softap.
2446 """
2447 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2448 callbackId) + wifi_constants.SOFTAP_INFOLIST_CHANGED
2449 ad.log.debug("softap info dump from eventStr %s", eventStr)
2450
2451 if (need_to_wait):
2452 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2453 infos = event['data']
2454
2455 events = ad.ed.pop_all(eventStr)
2456 for event in events:
2457 infos = event['data']
2458
2459 for info in infos:
2460 frequency = info[
2461 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2462 bandwidth = info[
2463 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2464 wifistandard = info[
2465 wifi_constants.SOFTAP_INFO_WIFISTANDARD_CALLBACK_KEY]
2466 bssid = info[
2467 wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
2468 ad.log.info(
2469 "softap info, freq:%s, bw:%s, wifistandard:%s, bssid:%s",
2470 frequency, bandwidth, wifistandard, bssid)
2471
2472 return infos
2473
2474def get_current_softap_capability(ad, callbackId, need_to_wait):
2475 """pop up all of softap info list changed event from queue.
2476 Args:
2477 callbackId: Id of the callback associated with registering.
2478 need_to_wait: Wait for the info callback event before pop all.
2479 Returns:
2480 Returns last updated capability of softap.
2481 """
2482 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2483 callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
2484 ad.log.debug("softap capability dump from eventStr %s", eventStr)
2485 if (need_to_wait):
2486 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2487 capability = event['data']
2488
2489 events = ad.ed.pop_all(eventStr)
2490 for event in events:
2491 capability = event['data']
2492
2493 return capability
lesl2f0fb232019-11-05 16:35:28 +08002494
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002495def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002496 """Pulls dumps in the ssrdump dir
2497 Args:
2498 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002499 """
2500 logs = ad.get_file_names("/data/vendor/ssrdump/")
2501 if logs:
2502 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002503 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002504 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002505 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002506 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002507 ignore_status=True)
2508
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002509
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002510def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002511 """Start packet capture in monitor mode.
2512
2513 Args:
2514 pcap: packet capture object
2515 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002516 test_name: test name to be used for pcap file name
2517
2518 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002519 Dictionary with wifi band as key and the tuple
2520 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002521 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002522 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002523 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002524 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002525 if wifi_band == 'dual':
2526 bands = [BAND_2G, BAND_5G]
2527 else:
2528 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002529 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002530 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002531 proc = pcap.start_packet_capture(band, log_dir, test_name)
2532 procs[band] = (proc, os.path.join(log_dir, test_name))
2533 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002534
Bindu Mahadevff295782019-02-08 16:17:48 -08002535
xianyuanjia0431ba32018-12-14 09:56:42 -08002536def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002537 """Stop packet capture in monitor mode.
2538
2539 Since, the pcap logs in monitor mode can be very large, we will
2540 delete them if they are not required. 'test_status' if True, will delete
2541 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002542
2543 Args:
2544 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002545 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002546 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002547 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002548 for proc, fname in procs.values():
2549 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002550
2551 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002552 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002553
Omar El Ayach8c017902020-10-18 10:26:57 -07002554
Jaineel95887fd2019-10-16 16:19:01 -07002555def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002556 """Verify that a mac address is not found in the captured packets.
2557
2558 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002559 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002560 mac: string representation of the mac address
2561 packets: packets obtained by rdpcap(pcap_fname)
2562 """
2563 for pkt in packets:
2564 logging.debug("Packet Summary = %s", pkt.summary())
2565 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002566 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2567 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002568
Omar El Ayach8c017902020-10-18 10:26:57 -07002569
Jaineel95887fd2019-10-16 16:19:01 -07002570def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002571 """Verify that a mac address is found in the captured packets.
2572
2573 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002574 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002575 mac: string representation of the mac address
2576 packets: packets obtained by rdpcap(pcap_fname)
2577 """
2578 for pkt in packets:
2579 if mac in pkt.summary():
2580 return
Jaineel95887fd2019-10-16 16:19:01 -07002581 asserts.fail("Did not find MAC = %s in packet sniffer."
2582 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002583
Omar El Ayach8c017902020-10-18 10:26:57 -07002584
Girish Moturuddc0d382020-08-24 12:08:41 -07002585def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002586 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002587 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002588
Bindu Mahadevff295782019-02-08 16:17:48 -08002589
Girish Moturuddc0d382020-08-24 12:08:41 -07002590def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002591 """Start cnss_diag to record extra wifi logs
2592
2593 Args:
2594 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002595 cnss_diag_file: cnss diag config file to push to device.
2596 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002597 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002598 if ad.model not in pixel_models:
2599 ad.log.info("Device not supported to collect pixel logger")
2600 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002601 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2602 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2603 else:
2604 prop = wifi_constants.CNSS_DIAG_PROP
2605 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002606 if not int(
2607 ad.adb.shell("ls -l %s%s | wc -l" %
2608 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002609 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002610 ad.adb.shell(
2611 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2612 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002613 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2614
Bindu Mahadevff295782019-02-08 16:17:48 -08002615
Girish Moturuddc0d382020-08-24 12:08:41 -07002616def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002617 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002618 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002619
Bindu Mahadevff295782019-02-08 16:17:48 -08002620
Girish Moturuddc0d382020-08-24 12:08:41 -07002621def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002622 """Stops cnss_diag
2623
2624 Args:
2625 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002626 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002627 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002628 if ad.model not in pixel_models:
2629 ad.log.info("Device not supported to collect pixel logger")
2630 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002631 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2632 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2633 else:
2634 prop = wifi_constants.CNSS_DIAG_PROP
2635 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2636
Bindu Mahadevff295782019-02-08 16:17:48 -08002637
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002638def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002639 """Pulls the cnss_diag logs in the wlan_logs dir
2640 Args:
2641 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002642 """
2643 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2644 if logs:
2645 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002646 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002647 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002648 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002649
Bindu Mahadevff295782019-02-08 16:17:48 -08002650
Omar El Ayach8c017902020-10-18 10:26:57 -07002651LinkProbeResult = namedtuple(
2652 'LinkProbeResult',
2653 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002654
2655
2656def send_link_probe(ad):
2657 """Sends a link probe to the currently connected AP, and returns whether the
2658 probe succeeded or not.
2659
2660 Args:
2661 ad: android device object
2662 Returns:
2663 LinkProbeResult namedtuple
2664 """
2665 stdout = ad.adb.shell('cmd wifi send-link-probe')
2666 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2667 'Exception while sending link probe: ' + stdout)
2668
2669 is_success = False
2670 elapsed_time = None
2671 failure_reason = None
2672 if 'succeeded' in stdout:
2673 is_success = True
2674 elapsed_time = next(
2675 (int(token) for token in stdout.split() if token.isdigit()), None)
2676 elif 'failed with reason' in stdout:
2677 failure_reason = next(
2678 (int(token) for token in stdout.split() if token.isdigit()), None)
2679 else:
2680 asserts.fail('Unexpected link probe result: ' + stdout)
2681
Omar El Ayach8c017902020-10-18 10:26:57 -07002682 return LinkProbeResult(is_success=is_success,
2683 stdout=stdout,
2684 elapsed_time=elapsed_time,
2685 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002686
2687
2688def send_link_probes(ad, num_probes, delay_sec):
2689 """Sends a sequence of link probes to the currently connected AP, and
2690 returns whether the probes succeeded or not.
2691
2692 Args:
2693 ad: android device object
2694 num_probes: number of probes to perform
2695 delay_sec: delay time between probes, in seconds
2696 Returns:
2697 List[LinkProbeResult] one LinkProbeResults for each probe
2698 """
2699 logging.info('Sending link probes')
2700 results = []
2701 for _ in range(num_probes):
2702 # send_link_probe() will also fail the test if it sees an exception
2703 # in the stdout of the adb shell command
2704 result = send_link_probe(ad)
2705 logging.info('link probe results: ' + str(result))
2706 results.append(result)
2707 time.sleep(delay_sec)
2708
2709 return results
2710
2711
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002712def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002713 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002714
2715 Args:
2716 test: the calling test class object.
2717 index: int, index of the AP.
2718 ap: access_point object of the AP.
2719 network: dict with information of the network, including ssid,
2720 password and bssid.
2721 bandwidth: the operation bandwidth for the AP, default 80MHz.
2722 channel: the channel number for the AP.
2723 Returns:
2724 brconfigs: the bridge interface configs
2725 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002726 bss_settings = []
2727 ssid = network[WifiEnums.SSID_KEY]
2728 test.access_points[index].close()
2729 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002730
Omar El Ayach8c017902020-10-18 10:26:57 -07002731 # Configure AP as required.
2732 if "password" in network.keys():
2733 password = network["password"]
2734 security = hostapd_security.Security(security_mode="wpa",
2735 password=password)
2736 else:
2737 security = hostapd_security.Security(security_mode=None, password=None)
2738 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2739 ssid=ssid,
2740 security=security,
2741 bss_settings=bss_settings,
2742 vht_bandwidth=bandwidth,
2743 profile_name='whirlwind',
2744 iface_wlan_2g=ap.wlan_2g,
2745 iface_wlan_5g=ap.wlan_5g)
2746 ap.start_ap(config)
2747 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002748
2749
2750def turn_ap_off(test, AP):
2751 """Bring down hostapd on the Access Point.
2752 Args:
2753 test: The test class object.
2754 AP: int, indicating which AP to turn OFF.
2755 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002756 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002757 if hostapd_2g.is_alive():
2758 hostapd_2g.stop()
2759 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002760 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002761 if hostapd_5g.is_alive():
2762 hostapd_5g.stop()
2763 logging.debug('Turned WLAN1 AP%d off' % AP)
2764
2765
2766def turn_ap_on(test, AP):
2767 """Bring up hostapd on the Access Point.
2768 Args:
2769 test: The test class object.
2770 AP: int, indicating which AP to turn ON.
2771 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002772 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002773 if not hostapd_2g.is_alive():
2774 hostapd_2g.start(hostapd_2g.config)
2775 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002776 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002777 if not hostapd_5g.is_alive():
2778 hostapd_5g.start(hostapd_5g.config)
2779 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002780
2781
2782def turn_location_off_and_scan_toggle_off(ad):
2783 """Turns off wifi location scans."""
2784 utils.set_location_service(ad, False)
2785 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2786 msg = "Failed to turn off location service's scan."
2787 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002788
2789
2790def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2791 """ Set SoftAP mode channel
2792
2793 Args:
2794 dut: android device object
2795 ap_iface: interface of SoftAP mode.
2796 cs_count: how many beacon frames before switch channel, default = 10
2797 channel: a wifi channel.
2798 """
2799 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002800 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002801 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002802 chan_switch_result = dut.adb.shell(
2803 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002804 if chan_switch_result == 'OK':
2805 dut.log.info('switch hotspot channel to {}'.format(channel))
2806 return chan_switch_result
2807
2808 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002809
2810def get_wlan0_link(dut):
2811 """ get wlan0 interface status"""
2812 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2813 out = dut.adb.shell(get_wlan0)
2814 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2815 asserts.assert_true("ssid" in out,
2816 "Client doesn't connect to any network")
Alfie Chenb3263dd2021-02-04 18:54:34 +08002817 return out
Girish Moturubea6c7e2021-05-07 16:24:27 -07002818
2819def verify_11ax_wifi_connection(ad, wifi6_supported_models, wifi6_ap):
2820 """Verify 11ax for wifi connection.
2821
2822 Args:
2823 ad: adndroid device object
2824 wifi6_supported_models: device supporting 11ax.
2825 wifi6_ap: if the AP supports 11ax.
2826 """
2827 if wifi6_ap and ad.model in wifi6_supported_models:
2828 logging.info("Verifying 11ax. Model: %s" % ad.model)
2829 asserts.assert_true(
2830 ad.droid.wifiGetConnectionStandard() ==
2831 wifi_constants.WIFI_STANDARD_11AX, "DUT did not connect to 11ax.")
2832
2833def verify_11ax_softap(dut, dut_client, wifi6_supported_models):
2834 """Verify 11ax SoftAp if devices support it.
2835
2836 Check if both DUT and DUT client supports 11ax, then SoftAp turns on
2837 with 11ax mode and DUT client can connect to it.
2838
2839 Args:
2840 dut: Softap device.
2841 dut_client: Client connecting to softap.
2842 wifi6_supported_models: List of device models supporting 11ax.
2843 """
2844 if dut.model in wifi6_supported_models and dut_client.model in wifi6_supported_models:
2845 logging.info(
2846 "Verifying 11ax softap. DUT model: %s, DUT Client model: %s",
2847 dut.model, dut_client.model)
2848 asserts.assert_true(
2849 dut_client.droid.wifiGetConnectionStandard() ==
2850 wifi_constants.WIFI_STANDARD_11AX,
2851 "DUT failed to start SoftAp in 11ax.")
“Alfie90ee7cb2021-04-20 23:16:12 +08002852
2853def check_available_channels_in_bands_2_5(dut, country_code):
2854 """Check if DUT is capable of enable BridgedAp.
2855 #TODO: Find a way to make this function flexible by taking an argument.
2856
2857 Args:
2858 country_code: country code, e.g., 'US', 'JP'.
2859 Returns:
2860 True: If DUT is capable of enable BridgedAp.
2861 False: If DUT is not capable of enable BridgedAp.
2862 """
2863 set_wifi_country_code(dut, country_code)
2864 country = dut.droid.wifiGetCountryCode()
2865 dut.log.info("DUT current country code : {}".format(country))
2866 # Wi-Fi ON and OFF to make sure country code take effet.
2867 wifi_toggle_state(dut, True)
2868 wifi_toggle_state(dut, False)
2869
2870 # Register SoftAp Callback and get SoftAp capability.
2871 callbackId = dut.droid.registerSoftApCallback()
2872 capability = get_current_softap_capability(dut, callbackId, True)
2873 dut.droid.unregisterSoftApCallback(callbackId)
2874
2875 if capability[wifi_constants.
2876 SOFTAP_CAPABILITY_24GHZ_SUPPORTED_CHANNEL_LIST] and \
2877 capability[wifi_constants.
2878 SOFTAP_CAPABILITY_5GHZ_SUPPORTED_CHANNEL_LIST]:
2879 return True
2880 return False
2881
2882
2883@retry(tries=5, delay=2)
2884def validate_ping_between_two_clients(dut1, dut2):
2885 """Make 2 DUT ping each other.
2886
2887 Args:
2888 dut1: An AndroidDevice object.
2889 dut2: An AndroidDevice object.
2890 """
2891 # Get DUTs' IPv4 addresses.
2892 dut1_ip = ""
2893 dut2_ip = ""
2894 try:
2895 dut1_ip = dut1.droid.connectivityGetIPv4Addresses('wlan0')[0]
2896 except IndexError as e:
2897 dut1.log.info(
2898 "{} has no Wi-Fi connection, cannot get IPv4 address."
2899 .format(dut1.serial))
2900 try:
2901 dut2_ip = dut2.droid.connectivityGetIPv4Addresses('wlan0')[0]
2902 except IndexError as e:
2903 dut2.log.info(
2904 "{} has no Wi-Fi connection, cannot get IPv4 address."
2905 .format(dut2.serial))
2906 # Test fail if not able to obtain two DUT's IPv4 addresses.
2907 asserts.assert_true(dut1_ip and dut2_ip,
2908 "Ping failed because no DUT's IPv4 address")
2909
2910 dut1.log.info("{} IPv4 addresses : {}".format(dut1.serial, dut1_ip))
2911 dut2.log.info("{} IPv4 addresses : {}".format(dut2.serial, dut2_ip))
2912
2913 # Two clients ping each other
2914 dut1.log.info("{} ping {}".format(dut1_ip, dut2_ip))
2915 asserts.assert_true(
2916 utils.adb_shell_ping(dut1, count=10, dest_ip=dut2_ip,
2917 timeout=20),
2918 "%s ping %s failed" % (dut1.serial, dut2_ip))
2919
2920 dut2.log.info("{} ping {}".format(dut2_ip, dut1_ip))
2921 asserts.assert_true(
2922 utils.adb_shell_ping(dut2, count=10, dest_ip=dut1_ip,
2923 timeout=20),
2924 "%s ping %s failed" % (dut2.serial, dut1_ip))
2925