blob: 716500c245b9097be8d88aa658d43de7fff17af4 [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
729 for n in networks:
730 ad.droid.wifiForgetNetwork(n['networkId'])
731 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800732 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700733 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800734 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700735 logging.warning("Could not confirm the removal of network %s.", n)
736 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800737 asserts.assert_true(
738 not ad.droid.wifiGetConfiguredNetworks(),
739 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700740
Ang Li73697b32015-12-03 00:41:53 +0000741
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700742def toggle_airplane_mode_on_and_off(ad):
743 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800744
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700745 ad: An AndroidDevice object.
746 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800747
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700748 """
749 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700750 asserts.assert_true(utils.force_airplane_mode(ad, True),
751 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700752 time.sleep(DEFAULT_TIMEOUT)
753 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700754 asserts.assert_true(utils.force_airplane_mode(ad, False),
755 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700756 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800757
758
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700759def toggle_wifi_off_and_on(ad):
760 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800761
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700762 ad: An AndroidDevice object.
763 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800764
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700765 """
766 ad.log.debug("Toggling wifi OFF.")
767 wifi_toggle_state(ad, False)
768 time.sleep(DEFAULT_TIMEOUT)
769 ad.log.debug("Toggling wifi ON.")
770 wifi_toggle_state(ad, True)
771 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800772
773
Ang Li73697b32015-12-03 00:41:53 +0000774def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800775 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000776
Ang Li8e767182015-12-09 17:29:24 -0800777 Args:
778 ad: android_device object for forget network.
779 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000780
Ang Li8e767182015-12-09 17:29:24 -0800781 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700782 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800783 if not networks:
784 return
785 for n in networks:
786 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700787 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800788 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800789 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800790 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800791 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700792 asserts.fail("Failed to remove network %s." % n)
Jimmy Chen8e40e152021-05-06 14:37:18 +0800793 break
Ang Li73697b32015-12-03 00:41:53 +0000794
Ang Li82522812016-06-02 13:57:21 -0700795
Ang Li73697b32015-12-03 00:41:53 +0000796def wifi_test_device_init(ad):
797 """Initializes an android device for wifi testing.
798
799 0. Make sure SL4A connection is established on the android device.
800 1. Disable location service's WiFi scan.
801 2. Turn WiFi on.
802 3. Clear all saved networks.
803 4. Set country code to US.
804 5. Enable WiFi verbose logging.
805 6. Sync device time with computer time.
806 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700807 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000808 """
Ang Lifee28402016-07-13 13:43:29 -0700809 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000810 ad.droid.wifiScannerToggleAlwaysAvailable(False)
811 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700812 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
813 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800814 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000815 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800816 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700817 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000818 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700819 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700820 output = ad.adb.shell(
821 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
822 "wlan0 log_level EXCESSIVE",
823 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700824 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700825 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800826 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700827 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700828 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000829
Omar El Ayach8c017902020-10-18 10:26:57 -0700830
Roshan Pius48df08c2019-09-13 08:07:30 -0700831def set_wifi_country_code(ad, country_code):
832 """Sets the wifi country code on the device.
833
834 Args:
835 ad: An AndroidDevice object.
836 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800837
838 Raises:
839 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700840 """
Jaineelc5b56a62019-10-10 17:12:02 -0700841 try:
codycaldwell35b87182020-01-16 14:08:01 -0800842 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000843 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700844 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700845
Ang Li82522812016-06-02 13:57:21 -0700846
Ang Li6b557182015-11-11 17:19:17 -0800847def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000848 """Starts a wifi connection scan and wait for results to become available.
849
850 Args:
Ang Li6b557182015-11-11 17:19:17 -0800851 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000852 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800853 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800854 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700855 try:
856 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
857 except Empty:
858 asserts.fail("Wi-Fi results did not become available within 60s.")
859
Ang Li73697b32015-12-03 00:41:53 +0000860
Roshan Piuscb9bc482018-02-01 14:27:09 -0800861def start_wifi_connection_scan_and_return_status(ad):
862 """
863 Starts a wifi connection scan and wait for results to become available
864 or a scan failure to be reported.
865
866 Args:
867 ad: An AndroidDevice object.
868 Returns:
869 True: if scan succeeded & results are available
870 False: if scan failed
871 """
872 ad.ed.clear_all_events()
873 ad.droid.wifiStartScan()
874 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700875 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
876 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800877 except Empty:
878 asserts.fail(
879 "Wi-Fi scan results/failure did not become available within 60s.")
880 # If there are multiple matches, we check for atleast one success.
881 for event in events:
882 if event["name"] == "WifiManagerScanResultsAvailable":
883 return True
884 elif event["name"] == "WifiManagerScanFailure":
885 ad.log.debug("Scan failure received")
886 return False
887
888
Omar El Ayach8c017902020-10-18 10:26:57 -0700889def start_wifi_connection_scan_and_check_for_network(ad,
890 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800891 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800892 """
893 Start connectivity scans & checks if the |network_ssid| is seen in
894 scan results. The method performs a max of |max_tries| connectivity scans
895 to find the network.
896
897 Args:
898 ad: An AndroidDevice object.
899 network_ssid: SSID of the network we are looking for.
900 max_tries: Number of scans to try.
901 Returns:
902 True: if network_ssid is found in scan results.
903 False: if network_ssid is not found in scan results.
904 """
905 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800906 if start_wifi_connection_scan_and_return_status(ad):
907 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700908 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
909 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800910 if len(match_results) > 0:
911 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800912 return False
913
914
Omar El Ayach8c017902020-10-18 10:26:57 -0700915def start_wifi_connection_scan_and_ensure_network_found(
916 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800917 """
918 Start connectivity scans & ensure the |network_ssid| is seen in
919 scan results. The method performs a max of |max_tries| connectivity scans
920 to find the network.
921 This method asserts on failure!
922
923 Args:
924 ad: An AndroidDevice object.
925 network_ssid: SSID of the network we are looking for.
926 max_tries: Number of scans to try.
927 """
928 ad.log.info("Starting scans to ensure %s is present", network_ssid)
929 assert_msg = "Failed to find " + network_ssid + " in scan results" \
930 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700931 asserts.assert_true(
932 start_wifi_connection_scan_and_check_for_network(
933 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800934
935
Omar El Ayach8c017902020-10-18 10:26:57 -0700936def start_wifi_connection_scan_and_ensure_network_not_found(
937 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800938 """
939 Start connectivity scans & ensure the |network_ssid| is not seen in
940 scan results. The method performs a max of |max_tries| connectivity scans
941 to find the network.
942 This method asserts on failure!
943
944 Args:
945 ad: An AndroidDevice object.
946 network_ssid: SSID of the network we are looking for.
947 max_tries: Number of scans to try.
948 """
949 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
950 assert_msg = "Found " + network_ssid + " in scan results" \
951 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700952 asserts.assert_false(
953 start_wifi_connection_scan_and_check_for_network(
954 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800955
956
Ang Li73697b32015-12-03 00:41:53 +0000957def start_wifi_background_scan(ad, scan_setting):
958 """Starts wifi background scan.
959
960 Args:
961 ad: android_device object to initiate connection on.
962 scan_setting: A dict representing the settings of the scan.
963
964 Returns:
965 If scan was started successfully, event data of success event is returned.
966 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700967 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
968 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800969 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000970 return event['data']
971
Ang Li82522812016-06-02 13:57:21 -0700972
Girish Moturu38b993c2021-03-25 13:03:50 -0700973def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
974 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000975 """Starts wifi tethering on an android_device.
976
977 Args:
978 ad: android_device to start wifi tethering on.
979 ssid: The SSID the soft AP should broadcast.
980 password: The password the soft AP should use.
981 band: The band the soft AP should be set on. It should be either
982 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800983 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700984 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000985
986 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700987 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000988 """
Ang Li82522812016-06-02 13:57:21 -0700989 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000990 if password:
991 config[WifiEnums.PWD_KEY] = password
992 if band:
lesl6d30a172020-03-05 15:05:22 +0800993 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800994 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -0700995 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -0700996 if security:
997 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -0700998 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
999 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -07001000 ad.droid.wifiStartTrackingTetherStateChange()
1001 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001002 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001003 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1004 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001005 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -07001006 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001007 except Empty:
1008 msg = "Failed to receive confirmation of wifi tethering starting"
1009 asserts.fail(msg)
1010 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001011 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001012
Bindu Mahadevff295782019-02-08 16:17:48 -08001013
Omar El Ayach8c017902020-10-18 10:26:57 -07001014def save_wifi_soft_ap_config(ad,
1015 wifi_config,
1016 band=None,
1017 hidden=None,
1018 security=None,
1019 password=None,
1020 channel=None,
1021 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001022 shutdown_timeout_enable=None,
1023 shutdown_timeout_millis=None,
1024 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001025 allowedList=None,
lesl67124362021-05-04 19:33:14 +08001026 blockedList=None,
1027 bands=None,
1028 channel_frequencys=None,
1029 mac_randomization_setting=None,
1030 bridged_opportunistic_shutdown_enabled=None,
1031 ieee80211ax_enabled=None):
lesl6d30a172020-03-05 15:05:22 +08001032 """ Save a soft ap configuration and verified
1033 Args:
1034 ad: android_device to set soft ap configuration.
1035 wifi_config: a soft ap configuration object, at least include SSID.
1036 band: specifies the band for the soft ap.
1037 hidden: specifies the soft ap need to broadcast its SSID or not.
1038 security: specifies the security type for the soft ap.
1039 password: specifies the password for the soft ap.
1040 channel: specifies the channel for the soft ap.
1041 max_clients: specifies the maximum connected client number.
1042 shutdown_timeout_enable: specifies the auto shut down enable or not.
1043 shutdown_timeout_millis: specifies the shut down timeout value.
1044 client_control_enable: specifies the client control enable or not.
1045 allowedList: specifies allowed clients list.
1046 blockedList: specifies blocked clients list.
lesl67124362021-05-04 19:33:14 +08001047 bands: specifies the band list for the soft ap.
1048 channel_frequencys: specifies the channel frequency list for soft ap.
1049 mac_randomization_setting: specifies the mac randomization setting.
1050 bridged_opportunistic_shutdown_enabled: specifies the opportunistic
1051 shutdown enable or not.
1052 ieee80211ax_enabled: specifies the ieee80211ax enable or not.
lesl6d30a172020-03-05 15:05:22 +08001053 """
1054 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001055 wifi_config[WifiEnums.SECURITY] = security
1056 wifi_config[WifiEnums.PWD_KEY] = password
lesl67124362021-05-04 19:33:14 +08001057 if hidden is not None:
Girish Moturu528b5442018-06-07 10:48:14 -07001058 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl67124362021-05-04 19:33:14 +08001059 if max_clients is not None:
lesl6d30a172020-03-05 15:05:22 +08001060 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
lesl67124362021-05-04 19:33:14 +08001061 if shutdown_timeout_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001062 wifi_config[
1063 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
lesl67124362021-05-04 19:33:14 +08001064 if shutdown_timeout_millis is not None:
Omar El Ayach8c017902020-10-18 10:26:57 -07001065 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl67124362021-05-04 19:33:14 +08001066 if client_control_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001067 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
lesl67124362021-05-04 19:33:14 +08001068 if allowedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001069 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
lesl67124362021-05-04 19:33:14 +08001070 if blockedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001071 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
lesl67124362021-05-04 19:33:14 +08001072 if mac_randomization_setting is not None:
1073 wifi_config[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY
1074 ] = mac_randomization_setting
1075 if bridged_opportunistic_shutdown_enabled is not None:
1076 wifi_config[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY
1077 ] = bridged_opportunistic_shutdown_enabled
1078 if ieee80211ax_enabled is not None:
1079 wifi_config[WifiEnums.AP_IEEE80211AX_ENABLED_KEY]= ieee80211ax_enabled
1080 if channel_frequencys is not None:
1081 wifi_config[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] = channel_frequencys
1082 elif bands is not None:
1083 wifi_config[WifiEnums.AP_BANDS_KEY] = bands
1084 elif band is not None:
1085 if channel is not None:
1086 wifi_config[WifiEnums.AP_BAND_KEY] = band
1087 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1088 else:
1089 wifi_config[WifiEnums.AP_BAND_KEY] = band
lesl6d30a172020-03-05 15:05:22 +08001090
1091 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001092 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001093 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1094
1095 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001096 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001097 del wifi_config[WifiEnums.SECURITY]
1098 del wifi_config[WifiEnums.PWD_KEY]
1099
Girish Moturu528b5442018-06-07 10:48:14 -07001100 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1101 "Failed to set WifiAp Configuration")
1102
1103 wifi_ap = ad.droid.wifiGetApConfiguration()
1104 asserts.assert_true(
1105 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001106 "Hotspot SSID doesn't match")
1107 if WifiEnums.SECURITY in wifi_config:
1108 asserts.assert_true(
1109 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1110 "Hotspot Security doesn't match")
1111 if WifiEnums.PWD_KEY in wifi_config:
1112 asserts.assert_true(
1113 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1114 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001115
lesl6d30a172020-03-05 15:05:22 +08001116 if WifiEnums.HIDDEN_KEY in wifi_config:
1117 asserts.assert_true(
1118 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1119 "Hotspot hidden setting doesn't match")
1120
lesl6d30a172020-03-05 15:05:22 +08001121 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1122 asserts.assert_true(
1123 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001124 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001125 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1126 asserts.assert_true(
1127 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001128 WifiEnums.AP_MAXCLIENTS_KEY],
1129 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001130 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1131 asserts.assert_true(
1132 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001133 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001134 "Hotspot ShutDown feature flag doesn't match")
1135 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1136 asserts.assert_true(
1137 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001138 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001139 "Hotspot ShutDown timeout setting doesn't match")
1140 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1141 asserts.assert_true(
1142 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001143 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001144 "Hotspot Client control flag doesn't match")
1145 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1146 asserts.assert_true(
1147 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001148 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001149 "Hotspot Allowed List doesn't match")
1150 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1151 asserts.assert_true(
1152 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001153 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001154 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001155
lesl67124362021-05-04 19:33:14 +08001156 if WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY in wifi_config:
1157 asserts.assert_true(
1158 wifi_ap[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY] == wifi_config[
1159 WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY],
1160 "Hotspot Mac randomization setting doesn't match")
1161
1162 if WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY in wifi_config:
1163 asserts.assert_true(
1164 wifi_ap[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY] == wifi_config[
1165 WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY],
1166 "Hotspot bridged shutdown enable setting doesn't match")
1167
1168 if WifiEnums.AP_IEEE80211AX_ENABLED_KEY in wifi_config:
1169 asserts.assert_true(
1170 wifi_ap[WifiEnums.AP_IEEE80211AX_ENABLED_KEY] == wifi_config[
1171 WifiEnums.AP_IEEE80211AX_ENABLED_KEY],
1172 "Hotspot 80211 AX enable setting doesn't match")
1173
1174 if WifiEnums.AP_CHANNEL_FREQUENCYS_KEY in wifi_config:
1175 asserts.assert_true(
1176 wifi_ap[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] == wifi_config[
1177 WifiEnums.AP_CHANNEL_FREQUENCYS_KEY],
1178 "Hotspot channels setting doesn't match")
Omar El Ayach8c017902020-10-18 10:26:57 -07001179
Girish Moturu528b5442018-06-07 10:48:14 -07001180def start_wifi_tethering_saved_config(ad):
1181 """ Turn on wifi hotspot with a config that is already saved """
1182 ad.droid.wifiStartTrackingTetherStateChange()
1183 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1184 try:
1185 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1186 ad.ed.wait_for_event("TetherStateChanged",
1187 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1188 except:
1189 asserts.fail("Didn't receive wifi tethering starting confirmation")
1190 finally:
1191 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001192
Bindu Mahadevff295782019-02-08 16:17:48 -08001193
Ang Li73697b32015-12-03 00:41:53 +00001194def stop_wifi_tethering(ad):
1195 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001196 Args:
1197 ad: android_device to stop wifi tethering on.
1198 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001199 ad.droid.wifiStartTrackingTetherStateChange()
1200 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001201 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001202 ad.ed.pop_event("WifiManagerApDisabled", 30)
1203 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001204 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001205 except Empty:
1206 msg = "Failed to receive confirmation of wifi tethering stopping"
1207 asserts.fail(msg)
1208 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001209 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001210
Ang Li76216d12016-09-20 14:51:57 -07001211
Roshan Pius58916a32016-06-16 16:26:44 -07001212def toggle_wifi_and_wait_for_reconnection(ad,
1213 network,
1214 num_of_tries=1,
1215 assert_on_fail=True):
1216 """Toggle wifi state and then wait for Android device to reconnect to
1217 the provided wifi network.
1218
1219 This expects the device to be already connected to the provided network.
1220
1221 Logic steps are
1222 1. Ensure that we're connected to the network.
1223 2. Turn wifi off.
1224 3. Wait for 10 seconds.
1225 4. Turn wifi on.
1226 5. Wait for the "connected" event, then confirm the connected ssid is the
1227 one requested.
1228
1229 Args:
1230 ad: android_device object to initiate connection on.
1231 network: A dictionary representing the network to await connection. The
1232 dictionary must have the key "SSID".
1233 num_of_tries: An integer that is the number of times to try before
1234 delaring failure. Default is 1.
1235 assert_on_fail: If True, error checks in this function will raise test
1236 failure signals.
1237
1238 Returns:
1239 If assert_on_fail is False, function returns True if the toggle was
1240 successful, False otherwise. If assert_on_fail is True, no return value.
1241 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001242 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1243 assert_on_fail,
1244 ad,
1245 network,
1246 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001247
1248
Girish Moturu5d9f4202019-12-03 15:29:21 -08001249def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001250 """Toggle wifi state and then wait for Android device to reconnect to
1251 the provided wifi network.
1252
1253 This expects the device to be already connected to the provided network.
1254
1255 Logic steps are
1256 1. Ensure that we're connected to the network.
1257 2. Turn wifi off.
1258 3. Wait for 10 seconds.
1259 4. Turn wifi on.
1260 5. Wait for the "connected" event, then confirm the connected ssid is the
1261 one requested.
1262
1263 This will directly fail a test if anything goes wrong.
1264
1265 Args:
1266 ad: android_device object to initiate connection on.
1267 network: A dictionary representing the network to await connection. The
1268 dictionary must have the key "SSID".
1269 num_of_tries: An integer that is the number of times to try before
1270 delaring failure. Default is 1.
1271 """
Roshan Pius58916a32016-06-16 16:26:44 -07001272 expected_ssid = network[WifiEnums.SSID_KEY]
1273 # First ensure that we're already connected to the provided network.
1274 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1275 verify_wifi_connection_info(ad, verify_con)
1276 # Now toggle wifi state and wait for the connection event.
1277 wifi_toggle_state(ad, False)
1278 time.sleep(10)
1279 wifi_toggle_state(ad, True)
1280 ad.droid.wifiStartTrackingStateChange()
1281 try:
1282 connect_result = None
1283 for i in range(num_of_tries):
1284 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001285 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001286 30)
1287 break
1288 except Empty:
1289 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001290 asserts.assert_true(
1291 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1292 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001293 logging.debug("Connection result on %s: %s.", ad.serial,
1294 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001295 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001296 asserts.assert_equal(
1297 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1298 "Expected %s, but got %s." %
1299 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001300 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1301 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001302 finally:
1303 ad.droid.wifiStopTrackingStateChange()
1304
1305
Omar El Ayach8c017902020-10-18 10:26:57 -07001306def wait_for_connect(ad,
1307 expected_ssid=None,
1308 expected_id=None,
1309 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001310 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001311 """Wait for a connect event.
1312
1313 This will directly fail a test if anything goes wrong.
1314
1315 Args:
1316 ad: An Android device object.
1317 expected_ssid: SSID of the network to connect to.
1318 expected_id: Network Id of the network to connect to.
1319 tries: An integer that is the number of times to try before failing.
1320 assert_on_fail: If True, error checks in this function will raise test
1321 failure signals.
1322
1323 Returns:
1324 Returns a value only if assert_on_fail is false.
1325 Returns True if the connection was successful, False otherwise.
1326 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001327 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1328 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001329
1330
Oscar Shucb9af9b2019-05-02 20:01:49 +00001331def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001332 """Wait for a connect event.
1333
1334 Args:
1335 ad: An Android device object.
1336 expected_ssid: SSID of the network to connect to.
1337 expected_id: Network Id of the network to connect to.
1338 tries: An integer that is the number of times to try before failing.
1339 """
1340 ad.droid.wifiStartTrackingStateChange()
1341 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001342 connect_result = _wait_for_connect_event(ad,
1343 ssid=expected_ssid,
1344 id=expected_id,
1345 tries=tries)
1346 asserts.assert_true(
1347 connect_result,
1348 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001349 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1350 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1351 if expected_ssid:
1352 asserts.assert_equal(actual_ssid, expected_ssid,
1353 "Connected to the wrong network")
1354 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1355 if expected_id:
1356 asserts.assert_equal(actual_id, expected_id,
1357 "Connected to the wrong network")
1358 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1359 except Empty:
1360 asserts.fail("Failed to start connection process to %s" %
1361 expected_ssid)
1362 except Exception as error:
1363 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1364 error)
1365 raise signals.TestFailure("Failed to connect to %s network" %
1366 expected_ssid)
1367 finally:
1368 ad.droid.wifiStopTrackingStateChange()
1369
1370
Oscar Shucb9af9b2019-05-02 20:01:49 +00001371def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001372 """Wait for a connect event on queue and pop when available.
1373
1374 Args:
1375 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001376 ssid: SSID of the network to connect to.
1377 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001378 tries: An integer that is the number of times to try before failing.
1379
1380 Returns:
1381 A dict with details of the connection data, which looks like this:
1382 {
1383 'time': 1485460337798,
1384 'name': 'WifiNetworkConnected',
1385 'data': {
1386 'rssi': -27,
1387 'is_24ghz': True,
1388 'mac_address': '02:00:00:00:00:00',
1389 'network_id': 1,
1390 'BSSID': '30:b5:c2:33:d3:fc',
1391 'ip_address': 117483712,
1392 'link_speed': 54,
1393 'supplicant_state': 'completed',
1394 'hidden_ssid': False,
1395 'SSID': 'wh_ap1_2g',
1396 'is_5ghz': False}
1397 }
1398
1399 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001400 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001401
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001402 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001403 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001404 for i in range(tries):
1405 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001406 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1407 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001408 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001409 except Empty:
1410 pass
1411 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001412 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001413 for i in range(tries):
1414 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001415 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1416 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001417 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1418 break
1419 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1420 break
1421 except Empty:
1422 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001423
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001424 return conn_result
1425
Bindu Mahadevff295782019-02-08 16:17:48 -08001426
Roshan Piusffc29912019-01-18 13:39:49 -08001427def wait_for_disconnect(ad, timeout=10):
1428 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001429
1430 Args:
1431 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001432 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001433
1434 """
1435 try:
1436 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001437 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001438 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001439 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001440 finally:
1441 ad.droid.wifiStopTrackingStateChange()
1442
1443
1444def ensure_no_disconnect(ad, duration=10):
1445 """Ensure that there is no disconnect for the specified duration.
1446
1447 Args:
1448 ad: Android device object.
1449 duration: Duration in seconds.
1450
1451 """
1452 try:
1453 ad.droid.wifiStartTrackingStateChange()
1454 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1455 raise signals.TestFailure("Device disconnected from the network")
1456 except Empty:
1457 pass
1458 finally:
1459 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001460
1461
Omar El Ayach8c017902020-10-18 10:26:57 -07001462def connect_to_wifi_network(ad,
1463 network,
1464 assert_on_fail=True,
1465 check_connectivity=True,
1466 hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001467 """Connection logic for open and psk wifi networks.
1468
1469 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001470 ad: AndroidDevice to use for connection
1471 network: network info of the network to connect to
1472 assert_on_fail: If true, errors from wifi_connect will raise
1473 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001474 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001475 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001476 if hidden:
1477 start_wifi_connection_scan_and_ensure_network_not_found(
1478 ad, network[WifiEnums.SSID_KEY])
1479 else:
1480 start_wifi_connection_scan_and_ensure_network_found(
1481 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001482 wifi_connect(ad,
1483 network,
1484 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001485 assert_on_fail=assert_on_fail,
1486 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001487
1488
1489def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1490 """Connect to the given network using network id and verify SSID.
1491
1492 Args:
1493 network_id: int Network Id of the network.
1494 network_ssid: string SSID of the network.
1495
1496 Returns: True if connect using network id was successful;
1497 False otherwise.
1498
1499 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001500 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001501 wifi_connect_by_id(ad, network_id)
1502 connect_data = ad.droid.wifiGetConnectionInfo()
1503 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1504 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001505 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001506 if connect_ssid != network_ssid:
1507 return False
1508 return True
1509
1510
Omar El Ayach8c017902020-10-18 10:26:57 -07001511def wifi_connect(ad,
1512 network,
1513 num_of_tries=1,
1514 assert_on_fail=True,
1515 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001516 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001517
1518 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001519 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001520
Ang Li82522812016-06-02 13:57:21 -07001521 This will directly fail a test if anything goes wrong.
1522
Ang Li73697b32015-12-03 00:41:53 +00001523 Args:
1524 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001525 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001526 dictionary must have the key "SSID".
1527 num_of_tries: An integer that is the number of times to try before
1528 delaring failure. Default is 1.
1529 assert_on_fail: If True, error checks in this function will raise test
1530 failure signals.
1531
1532 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001533 Returns a value only if assert_on_fail is false.
1534 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001535 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001536 return _assert_on_fail_handler(_wifi_connect,
1537 assert_on_fail,
1538 ad,
1539 network,
1540 num_of_tries=num_of_tries,
1541 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001542
1543
Oscar Shucb9af9b2019-05-02 20:01:49 +00001544def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001545 """Connect an Android device to a wifi network.
1546
1547 Initiate connection to a wifi network, wait for the "connected" event, then
1548 confirm the connected ssid is the one requested.
1549
1550 This will directly fail a test if anything goes wrong.
1551
1552 Args:
1553 ad: android_device object to initiate connection on.
1554 network: A dictionary representing the network to connect to. The
1555 dictionary must have the key "SSID".
1556 num_of_tries: An integer that is the number of times to try before
1557 delaring failure. Default is 1.
1558 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001559 asserts.assert_true(
1560 WifiEnums.SSID_KEY in network,
1561 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001562 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001563 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001564 ad.droid.wifiConnectByConfig(network)
1565 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001566 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001567 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001568 connect_result = _wait_for_connect_event(ad,
1569 ssid=expected_ssid,
1570 tries=num_of_tries)
1571 asserts.assert_true(
1572 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1573 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001574 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001575 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001576 asserts.assert_equal(
1577 actual_ssid, expected_ssid,
1578 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001579 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001580
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001581 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001582 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001583 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001584 raise signals.TestFailure(
1585 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001586 except Empty:
1587 asserts.fail("Failed to start connection process to %s on %s" %
1588 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001589 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001590 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1591 error)
1592 raise signals.TestFailure("Failed to connect to %s network" % network)
1593
Ang Li73697b32015-12-03 00:41:53 +00001594 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001595 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001596
Bindu Mahadev50374df2017-01-04 11:03:32 -08001597
Oscar Shucb9af9b2019-05-02 20:01:49 +00001598def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001599 """Connect an Android device to a wifi network using network Id.
1600
1601 Start connection to the wifi network, with the given network Id, wait for
1602 the "connected" event, then verify the connected network is the one requested.
1603
1604 This will directly fail a test if anything goes wrong.
1605
1606 Args:
1607 ad: android_device object to initiate connection on.
1608 network_id: Integer specifying the network id of the network.
1609 num_of_tries: An integer that is the number of times to try before
1610 delaring failure. Default is 1.
1611 assert_on_fail: If True, error checks in this function will raise test
1612 failure signals.
1613
1614 Returns:
1615 Returns a value only if assert_on_fail is false.
1616 Returns True if the connection was successful, False otherwise.
1617 """
1618 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001619 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001620
1621
Oscar Shucb9af9b2019-05-02 20:01:49 +00001622def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001623 """Connect an Android device to a wifi network using it's network id.
1624
1625 Start connection to the wifi network, with the given network id, wait for
1626 the "connected" event, then verify the connected network is the one requested.
1627
1628 Args:
1629 ad: android_device object to initiate connection on.
1630 network_id: Integer specifying the network id of the network.
1631 num_of_tries: An integer that is the number of times to try before
1632 delaring failure. Default is 1.
1633 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001634 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001635 # Clear all previous events.
1636 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001637 ad.droid.wifiConnectByNetworkId(network_id)
1638 ad.log.info("Starting connection to network with id %d", network_id)
1639 try:
1640 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001641 connect_result = _wait_for_connect_event(ad,
1642 id=network_id,
1643 tries=num_of_tries)
1644 asserts.assert_true(
1645 connect_result,
1646 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001647 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1648 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001649 asserts.assert_equal(
1650 actual_id, network_id, "Connected to the wrong network on %s."
1651 "Expected network id = %d, but got %d." %
1652 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001653 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1654 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001655 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001656
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001657 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1658 if not internet:
1659 raise signals.TestFailure("Failed to connect to internet on %s" %
1660 expected_ssid)
1661 except Empty:
1662 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001663 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001664 except Exception as error:
1665 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001666 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001667 raise signals.TestFailure("Failed to connect to network with network"
1668 " id %d" % network_id)
1669 finally:
1670 ad.droid.wifiStopTrackingStateChange()
1671
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001672
Omar El Ayach8c017902020-10-18 10:26:57 -07001673def wifi_connect_using_network_request(ad,
1674 network,
1675 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001676 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001677 """Connect an Android device to a wifi network using network request.
1678
1679 Trigger a network request with the provided network specifier,
1680 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1681 event contain the specified network, then simulate the user granting the
1682 request with the specified network selected. Then wait for the "onAvailable"
1683 network callback indicating successful connection to network.
1684
1685 Args:
1686 ad: android_device object to initiate connection on.
1687 network_specifier: A dictionary representing the network specifier to
1688 use.
1689 network: A dictionary representing the network to connect to. The
1690 dictionary must have the key "SSID".
1691 num_of_tries: An integer that is the number of times to try before
1692 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001693 Returns:
1694 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001695 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001696 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1697 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001698 # Need a delay here because UI interaction should only start once wifi
1699 # starts processing the request.
1700 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001701 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1702 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001703
1704
Omar El Ayach8c017902020-10-18 10:26:57 -07001705def wait_for_wifi_connect_after_network_request(ad,
1706 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001707 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001708 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001709 assert_on_fail=True):
1710 """
1711 Simulate and verify the connection flow after initiating the network
1712 request.
1713
1714 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1715 event contain the specified network, then simulate the user granting the
1716 request with the specified network selected. Then wait for the "onAvailable"
1717 network callback indicating successful connection to network.
1718
1719 Args:
1720 ad: android_device object to initiate connection on.
1721 network: A dictionary representing the network to connect to. The
1722 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001723 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001724 num_of_tries: An integer that is the number of times to try before
1725 delaring failure.
1726 assert_on_fail: If True, error checks in this function will raise test
1727 failure signals.
1728
1729 Returns:
1730 Returns a value only if assert_on_fail is false.
1731 Returns True if the connection was successful, False otherwise.
1732 """
1733 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001734 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001735
1736
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001737def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001738 """
1739 Simulate and verify the connection flow after initiating the network
1740 request.
1741
1742 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1743 event contain the specified network, then simulate the user granting the
1744 request with the specified network selected. Then wait for the "onAvailable"
1745 network callback indicating successful connection to network.
1746
1747 Args:
1748 ad: android_device object to initiate connection on.
1749 network: A dictionary representing the network to connect to. The
1750 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001751 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001752 num_of_tries: An integer that is the number of times to try before
1753 delaring failure.
1754 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001755 asserts.assert_true(
1756 WifiEnums.SSID_KEY in network,
1757 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001758 ad.droid.wifiStartTrackingStateChange()
1759 expected_ssid = network[WifiEnums.SSID_KEY]
1760 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1761 # Wait for the platform to scan and return a list of networks
1762 # matching the request
1763 try:
1764 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001765 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001766 on_match_event = ad.ed.pop_event(
1767 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1768 asserts.assert_true(on_match_event,
1769 "Network request on match not received.")
1770 matched_scan_results = on_match_event["data"]
1771 ad.log.debug("Network request on match results %s",
1772 matched_scan_results)
1773 matched_network = match_networks(
1774 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1775 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001776 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001777 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001778 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001779
Omar El Ayach8c017902020-10-18 10:26:57 -07001780 asserts.assert_true(matched_network,
1781 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001782
1783 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1784 ad.log.info("Sent user selection for network request %s",
1785 expected_ssid)
1786
1787 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001788 autils.wait_for_event_with_keys(
1789 ad, cconsts.EVENT_NETWORK_CALLBACK,
1790 60,
1791 (cconsts.NETWORK_CB_KEY_ID, key),
1792 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1793 on_capabilities_changed = autils.wait_for_event_with_keys(
1794 ad, cconsts.EVENT_NETWORK_CALLBACK,
1795 10,
1796 (cconsts.NETWORK_CB_KEY_ID, key),
1797 (cconsts.NETWORK_CB_KEY_EVENT,
1798 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001799 connected_network = None
1800 # WifiInfo is attached to TransportInfo only in S.
1801 if ad.droid.isSdkAtLeastS():
1802 connected_network = (
1803 on_capabilities_changed["data"][
1804 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1805 )
1806 else:
1807 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001808 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001809 asserts.assert_equal(
1810 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1811 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001812 "Expected %s, but got %s."
1813 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001814 except Empty:
1815 asserts.fail("Failed to connect to %s" % expected_ssid)
1816 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001817 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001818 (expected_ssid, error))
1819 raise signals.TestFailure("Failed to connect to %s network" % network)
1820 finally:
1821 ad.droid.wifiStopTrackingStateChange()
1822
1823
Omar El Ayach8c017902020-10-18 10:26:57 -07001824def wifi_passpoint_connect(ad,
1825 passpoint_network,
1826 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001827 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001828 """Connect an Android device to a wifi network.
1829
1830 Initiate connection to a wifi network, wait for the "connected" event, then
1831 confirm the connected ssid is the one requested.
1832
1833 This will directly fail a test if anything goes wrong.
1834
1835 Args:
1836 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001837 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001838 num_of_tries: An integer that is the number of times to try before
1839 delaring failure. Default is 1.
1840 assert_on_fail: If True, error checks in this function will raise test
1841 failure signals.
1842
1843 Returns:
1844 If assert_on_fail is False, function returns network id, if the connect was
1845 successful, False otherwise. If assert_on_fail is True, no return value.
1846 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001847 _assert_on_fail_handler(_wifi_passpoint_connect,
1848 assert_on_fail,
1849 ad,
1850 passpoint_network,
1851 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001852
1853
Oscar Shucb9af9b2019-05-02 20:01:49 +00001854def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001855 """Connect an Android device to a wifi network.
1856
1857 Initiate connection to a wifi network, wait for the "connected" event, then
1858 confirm the connected ssid is the one requested.
1859
1860 This will directly fail a test if anything goes wrong.
1861
1862 Args:
1863 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001864 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001865 num_of_tries: An integer that is the number of times to try before
1866 delaring failure. Default is 1.
1867 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001868 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001869 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001870 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1871
1872 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001873 connect_result = _wait_for_connect_event(ad, expected_ssid,
1874 num_of_tries)
1875 asserts.assert_true(
1876 connect_result, "Failed to connect to WiFi passpoint network %s on"
1877 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001878 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1879 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001880 asserts.assert_equal(
1881 actual_ssid, expected_ssid,
1882 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001883 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1884
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001885 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1886 if not internet:
1887 raise signals.TestFailure("Failed to connect to internet on %s" %
1888 expected_ssid)
1889 except Exception as error:
1890 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001891 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001892 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001893 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001894
1895 finally:
1896 ad.droid.wifiStopTrackingStateChange()
1897
1898
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001899def delete_passpoint(ad, fqdn):
1900 """Delete a required Passpoint configuration."""
1901 try:
1902 ad.droid.removePasspointConfig(fqdn)
1903 return True
1904 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001905 ad.log.error(
1906 "Failed to remove passpoint configuration with FQDN=%s "
1907 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001908 return False
1909
1910
Ang Li73697b32015-12-03 00:41:53 +00001911def start_wifi_single_scan(ad, scan_setting):
1912 """Starts wifi single shot scan.
1913
1914 Args:
1915 ad: android_device object to initiate connection on.
1916 scan_setting: A dict representing the settings of the scan.
1917
1918 Returns:
1919 If scan was started successfully, event data of success event is returned.
1920 """
Ang Li82522812016-06-02 13:57:21 -07001921 idx = ad.droid.wifiScannerStartScan(scan_setting)
1922 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001923 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001924 return event['data']
1925
Ang Li82522812016-06-02 13:57:21 -07001926
Ang Li73697b32015-12-03 00:41:53 +00001927def track_connection(ad, network_ssid, check_connection_count):
1928 """Track wifi connection to network changes for given number of counts
1929
1930 Args:
1931 ad: android_device object for forget network.
1932 network_ssid: network ssid to which connection would be tracked
1933 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001934 check.
Ang Li73697b32015-12-03 00:41:53 +00001935 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001936 True if connection to given network happen, else return False.
1937 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001938 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001939 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001940 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001941 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001942 if (WifiEnums.SSID_KEY in connect_network['data'] and
1943 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1944 return True
Ang Li8e767182015-12-09 17:29:24 -08001945 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001946 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001947 return False
1948
Ang Li82522812016-06-02 13:57:21 -07001949
Ang Li73697b32015-12-03 00:41:53 +00001950def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1951 """Calculate the scan time required based on the band or channels in scan
1952 setting
1953
1954 Args:
1955 wifi_chs: Object of channels supported
1956 scan_setting: scan setting used for start scan
1957 stime_channel: scan time per channel
1958
1959 Returns:
1960 scan_time: time required for completing a scan
1961 scan_channels: channel used for scanning
1962 """
1963 scan_time = 0
1964 scan_channels = []
1965 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001966 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001967 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001968 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001969 scan_time = len(scan_channels) * stime_channel
1970 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001971 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001972 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001973 return scan_time, scan_channels
1974
Ang Li82522812016-06-02 13:57:21 -07001975
Ang Li73697b32015-12-03 00:41:53 +00001976def start_wifi_track_bssid(ad, track_setting):
1977 """Start tracking Bssid for the given settings.
1978
1979 Args:
1980 ad: android_device object.
1981 track_setting: Setting for which the bssid tracking should be started
1982
1983 Returns:
1984 If tracking started successfully, event data of success event is returned.
1985 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001986 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001987 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001988 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001989 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001990 return event['data']
1991
Ang Li82522812016-06-02 13:57:21 -07001992
Ang Li73697b32015-12-03 00:41:53 +00001993def convert_pem_key_to_pkcs8(in_file, out_file):
1994 """Converts the key file generated by us to the format required by
1995 Android using openssl.
1996
1997 The input file must have the extension "pem". The output file must
1998 have the extension "der".
1999
2000 Args:
2001 in_file: The original key file.
2002 out_file: The full path to the converted key file, including
2003 filename.
2004 """
Ang Li82522812016-06-02 13:57:21 -07002005 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07002006 asserts.assert_true(out_file.endswith(".der"),
2007 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00002008 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
2009 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07002010 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00002011
Ang Li82522812016-06-02 13:57:21 -07002012
Omar El Ayach8c017902020-10-18 10:26:57 -07002013def validate_connection(ad,
2014 ping_addr=DEFAULT_PING_ADDR,
2015 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08002016 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00002017 """Validate internet connection by pinging the address provided.
2018
2019 Args:
2020 ad: android_device object.
2021 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07002022 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00002023
2024 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08002025 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00002026 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07002027 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002028 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08002029 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07002030 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002031 break
2032 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08002033 ping = False
2034 try:
2035 ping = ad.droid.httpPing(ping_addr)
2036 ad.log.info("Http ping result: %s.", ping)
2037 except:
2038 pass
2039 if not ping and ping_gateway:
2040 ad.log.info("Http ping failed. Pinging default gateway")
2041 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2042 result = ad.adb.shell("ping -c 6 {}".format(gw))
2043 ad.log.info("Default gateway ping result: %s" % result)
2044 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002045 return ping
2046
Ang Li82522812016-06-02 13:57:21 -07002047
Ang Li73697b32015-12-03 00:41:53 +00002048#TODO(angli): This can only verify if an actual value is exactly the same.
2049# Would be nice to be able to verify an actual value is one of serveral.
2050def verify_wifi_connection_info(ad, expected_con):
2051 """Verifies that the information of the currently connected wifi network is
2052 as expected.
2053
2054 Args:
2055 expected_con: A dict representing expected key-value pairs for wifi
2056 connection. e.g. {"SSID": "test_wifi"}
2057 """
2058 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002059 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002060 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002061 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002062 # Do not verify authentication related fields.
2063 if k == "password":
2064 continue
Ang Li82522812016-06-02 13:57:21 -07002065 msg = "Field %s does not exist in wifi connection info %s." % (
2066 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002067 if k not in current_con:
2068 raise signals.TestFailure(msg)
2069 actual_v = current_con[k]
2070 if k in case_insensitive:
2071 actual_v = actual_v.lower()
2072 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002073 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002074 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002075 if actual_v != expected_v:
2076 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002077
Ang Li82522812016-06-02 13:57:21 -07002078
Omar El Ayach8c017902020-10-18 10:26:57 -07002079def check_autoconnect_to_open_network(
2080 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002081 """Connects to any open WiFI AP
2082 Args:
2083 timeout value in sec to wait for UE to connect to a WiFi AP
2084 Returns:
2085 True if UE connects to WiFi AP (supplicant_state = completed)
2086 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2087 """
2088 if ad.droid.wifiCheckState():
2089 return True
2090 ad.droid.wifiToggleState()
2091 wifi_connection_state = None
2092 timeout = time.time() + conn_timeout
2093 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002094 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2095 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002096 if time.time() > timeout:
2097 ad.log.warning("Failed to connect to WiFi AP")
2098 return False
2099 return True
2100
2101
Ang Li73697b32015-12-03 00:41:53 +00002102def expand_enterprise_config_by_phase2(config):
2103 """Take an enterprise config and generate a list of configs, each with
2104 a different phase2 auth type.
2105
2106 Args:
2107 config: A dict representing enterprise config.
2108
2109 Returns
2110 A list of enterprise configs.
2111 """
2112 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002113 phase2_types = WifiEnums.EapPhase2
2114 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2115 # Skip unsupported phase2 types for PEAP.
2116 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2117 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002118 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002119 if (WifiEnums.Enterprise.FQDN in config
2120 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002121 continue
2122 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002123 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002124 results.append(c)
2125 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002126
2127
Girish Moturub48a13c2017-02-27 11:36:42 -08002128def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002129 """ Generates a test case name based on an EAP configuration.
2130
2131 Args:
2132 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002133 ad object: Redundant but required as the same param is passed
2134 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002135
2136 Returns:
2137 A string representing the name of a generated EAP test case.
2138 """
2139 eap = WifiEnums.Eap
2140 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002141 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002142 name = "test_connect-"
2143 eap_name = ""
2144 for e in eap:
2145 if e.value == config[Ent.EAP]:
2146 eap_name = e.name
2147 break
2148 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2149 eap_name = "PEAP0"
2150 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2151 eap_name = "PEAP1"
2152 name += eap_name
2153 if Ent.PHASE2 in config:
2154 for e in eap_phase2:
2155 if e.value == config[Ent.PHASE2]:
2156 name += "-{}".format(e.name)
2157 break
2158 return name
2159
2160
Ang Li2d3fe982016-06-08 10:00:43 -07002161def group_attenuators(attenuators):
2162 """Groups a list of attenuators into attenuator groups for backward
2163 compatibility reasons.
2164
2165 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2166 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2167 on an AP, so two of them are connected to one AP.
2168
2169 To make the existing scripts work in the new setup, when the script needs
2170 to attenuate one AP, it needs to set attenuation on both attenuators
2171 connected to the same AP.
2172
2173 This function groups attenuators properly so the scripts work in both
2174 legacy and new Wi-Fi setups.
2175
2176 Args:
2177 attenuators: A list of attenuator objects, either two or four in length.
2178
2179 Raises:
2180 signals.TestFailure is raised if the attenuator list does not have two
2181 or four objects.
2182 """
2183 attn0 = attenuator.AttenuatorGroup("AP0")
2184 attn1 = attenuator.AttenuatorGroup("AP1")
2185 # Legacy testbed setup has two attenuation channels.
2186 num_of_attns = len(attenuators)
2187 if num_of_attns == 2:
2188 attn0.add(attenuators[0])
2189 attn1.add(attenuators[1])
2190 elif num_of_attns == 4:
2191 attn0.add(attenuators[0])
2192 attn0.add(attenuators[1])
2193 attn1.add(attenuators[2])
2194 attn1.add(attenuators[3])
2195 else:
2196 asserts.fail(("Either two or four attenuators are required for this "
2197 "test, but found %s") % num_of_attns)
2198 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002199
Bindu Mahadevff295782019-02-08 16:17:48 -08002200
Girish Moturu36348a32019-12-10 08:41:54 -08002201def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002202 """Sets attenuation values on attenuators used in this test.
2203
2204 Args:
2205 attenuator: The attenuator object.
2206 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002207 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002208 """
2209 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2210 try:
2211 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2212 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2213 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2214 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2215 except:
2216 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002217 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002218 raise
2219
Omar El Ayach8c017902020-10-18 10:26:57 -07002220
Girish Moturu36348a32019-12-10 08:41:54 -08002221def set_attns_steps(attenuators,
2222 atten_val_name,
2223 roaming_attn=ROAMING_ATTN,
2224 steps=10,
2225 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002226 """Set attenuation values on attenuators used in this test. It will change
2227 the attenuation values linearly from current value to target value step by
2228 step.
2229
2230 Args:
2231 attenuators: The list of attenuator objects that you want to change
2232 their attenuation value.
2233 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002234 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002235 steps: Number of attenuator changes to reach the target value.
2236 wait_time: Sleep time for each change of attenuator.
2237 """
2238 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002239 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002240 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2241 target_atten = roaming_attn[atten_val_name]
2242 for current_step in range(steps):
2243 progress = (current_step + 1) / steps
2244 for i, attenuator in enumerate(attenuators):
2245 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2246 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2247 time.sleep(wait_time)
2248
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002249
Girish Moturu36348a32019-12-10 08:41:54 -08002250def trigger_roaming_and_validate(dut,
2251 attenuator,
2252 attn_val_name,
2253 expected_con,
2254 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002255 """Sets attenuators to trigger roaming and validate the DUT connected
2256 to the BSSID expected.
2257
2258 Args:
2259 attenuator: The attenuator object.
2260 attn_val_name: Name of the attenuation value pair to use.
2261 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002262 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002263 """
2264 expected_con = {
2265 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2266 WifiEnums.BSSID_KEY: expected_con["bssid"],
2267 }
Girish Moturu36348a32019-12-10 08:41:54 -08002268 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002269
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002270 verify_wifi_connection_info(dut, expected_con)
2271 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2272 logging.info("Roamed to %s successfully", expected_bssid)
2273 if not validate_connection(dut):
2274 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002275 expected_bssid)
2276
Jong Wook Kim92356922018-02-06 18:32:49 -08002277
2278def create_softap_config():
2279 """Create a softap config with random ssid and password."""
2280 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2281 ap_password = utils.rand_ascii_str(8)
2282 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2283 config = {
2284 WifiEnums.SSID_KEY: ap_ssid,
2285 WifiEnums.PWD_KEY: ap_password,
2286 }
2287 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002288
Omar El Ayach8c017902020-10-18 10:26:57 -07002289
Bindu Mahadevff295782019-02-08 16:17:48 -08002290def start_softap_and_verify(ad, band):
2291 """Bring-up softap and verify AP mode and in scan results.
2292
2293 Args:
2294 band: The band to use for softAP.
2295
2296 Returns: dict, the softAP config.
2297
2298 """
lesl2f0fb232019-11-05 16:35:28 +08002299 # Register before start the test.
2300 callbackId = ad.dut.droid.registerSoftApCallback()
2301 # Check softap info value is default
2302 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2303 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2304 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2305
Bindu Mahadevff295782019-02-08 16:17:48 -08002306 config = create_softap_config()
2307 start_wifi_tethering(ad.dut,
2308 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002309 config[WifiEnums.PWD_KEY],
2310 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002311 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002312 "SoftAp is not reported as running")
2313 start_wifi_connection_scan_and_ensure_network_found(
2314 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002315
2316 # Check softap info can get from callback succeed and assert value should be
2317 # valid.
2318 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2319 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2320 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2321 # Unregister callback
2322 ad.dut.droid.unregisterSoftApCallback(callbackId)
2323
Bindu Mahadevff295782019-02-08 16:17:48 -08002324 return config
2325
Omar El Ayach8c017902020-10-18 10:26:57 -07002326
lesle8e3c0a2019-02-22 17:06:04 +08002327def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002328 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002329 """Wait for the number of softap clients to be updated as expected.
2330 Args:
2331 callbackId: Id of the callback associated with registering.
2332 expected_num_of_softap_clients: expected number of softap clients.
2333 """
2334 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002335 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002336 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2337 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002338 clientMacAddresses = clientData[
2339 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2340 asserts.assert_equal(
2341 clientCount, expected_num_of_softap_clients,
2342 "The number of softap clients doesn't match the expected number")
2343 asserts.assert_equal(
2344 len(clientMacAddresses), expected_num_of_softap_clients,
2345 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002346 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002347 asserts.assert_true(checkMacAddress(macAddress),
2348 "An invalid mac address was returned")
2349
James Mattis5a5dd492020-05-14 13:09:43 -07002350
2351def checkMacAddress(input):
2352 """Validate whether a string is a valid mac address or not.
2353
2354 Args:
2355 input: The string to validate.
2356
2357 Returns: True/False, returns true for a valid mac address and false otherwise.
2358 """
2359 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2360 if re.match(macValidationRegex, input.lower()):
2361 return True
2362 return False
lesle8e3c0a2019-02-22 17:06:04 +08002363
Omar El Ayach8c017902020-10-18 10:26:57 -07002364
lesle8e3c0a2019-02-22 17:06:04 +08002365def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2366 """Wait for the expected softap state change.
2367 Args:
2368 callbackId: Id of the callback associated with registering.
2369 expected_softap_state: The expected softap state.
2370 """
2371 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002372 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2373 asserts.assert_equal(
2374 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2375 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2376 expected_softap_state,
2377 "Softap state doesn't match with expected state")
2378
lesle8e3c0a2019-02-22 17:06:04 +08002379
2380def get_current_number_of_softap_clients(ad, callbackId):
2381 """pop up all of softap client updated event from queue.
2382 Args:
2383 callbackId: Id of the callback associated with registering.
2384
2385 Returns:
2386 If exist aleast callback, returns last updated number_of_softap_clients.
2387 Returns None when no any match callback event in queue.
2388 """
2389 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002390 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002391 events = ad.ed.pop_all(eventStr)
2392 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002393 num_of_clients = event['data'][
2394 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002395 if len(events) == 0:
2396 return None
2397 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002398
Omar El Ayach8c017902020-10-18 10:26:57 -07002399
lesl67124362021-05-04 19:33:14 +08002400def get_current_softap_info(ad, callbackId, need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002401 """pop up all of softap info changed event from queue.
2402 Args:
2403 callbackId: Id of the callback associated with registering.
lesl67124362021-05-04 19:33:14 +08002404 need_to_wait: Wait for the info callback event before pop all.
lesl2f0fb232019-11-05 16:35:28 +08002405 Returns:
2406 Returns last updated information of softap.
2407 """
2408 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002409 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
lesl67124362021-05-04 19:33:14 +08002410 ad.log.debug("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002411 frequency = 0
2412 bandwidth = 0
lesl67124362021-05-04 19:33:14 +08002413 if (need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002414 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002415 frequency = event['data'][
2416 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2417 bandwidth = event['data'][
2418 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002419 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002420 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002421
2422 events = ad.ed.pop_all(eventStr)
2423 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002424 frequency = event['data'][
2425 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2426 bandwidth = event['data'][
2427 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2428 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2429 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002430 return frequency, bandwidth
2431
lesl67124362021-05-04 19:33:14 +08002432def get_current_softap_infos(ad, callbackId, need_to_wait):
2433 """pop up all of softap info list changed event from queue.
2434 Args:
2435 callbackId: Id of the callback associated with registering.
2436 need_to_wait: Wait for the info callback event before pop all.
2437 Returns:
2438 Returns last updated informations of softap.
2439 """
2440 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2441 callbackId) + wifi_constants.SOFTAP_INFOLIST_CHANGED
2442 ad.log.debug("softap info dump from eventStr %s", eventStr)
2443
2444 if (need_to_wait):
2445 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2446 infos = event['data']
2447
2448 events = ad.ed.pop_all(eventStr)
2449 for event in events:
2450 infos = event['data']
2451
2452 for info in infos:
2453 frequency = info[
2454 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2455 bandwidth = info[
2456 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2457 wifistandard = info[
2458 wifi_constants.SOFTAP_INFO_WIFISTANDARD_CALLBACK_KEY]
2459 bssid = info[
2460 wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
2461 ad.log.info(
2462 "softap info, freq:%s, bw:%s, wifistandard:%s, bssid:%s",
2463 frequency, bandwidth, wifistandard, bssid)
2464
2465 return infos
2466
2467def get_current_softap_capability(ad, callbackId, need_to_wait):
2468 """pop up all of softap info list changed event from queue.
2469 Args:
2470 callbackId: Id of the callback associated with registering.
2471 need_to_wait: Wait for the info callback event before pop all.
2472 Returns:
2473 Returns last updated capability of softap.
2474 """
2475 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2476 callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
2477 ad.log.debug("softap capability dump from eventStr %s", eventStr)
2478 if (need_to_wait):
2479 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2480 capability = event['data']
2481
2482 events = ad.ed.pop_all(eventStr)
2483 for event in events:
2484 capability = event['data']
2485
2486 return capability
lesl2f0fb232019-11-05 16:35:28 +08002487
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002488def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002489 """Pulls dumps in the ssrdump dir
2490 Args:
2491 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002492 """
2493 logs = ad.get_file_names("/data/vendor/ssrdump/")
2494 if logs:
2495 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002496 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002497 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002498 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002499 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002500 ignore_status=True)
2501
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002502
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002503def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002504 """Start packet capture in monitor mode.
2505
2506 Args:
2507 pcap: packet capture object
2508 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002509 test_name: test name to be used for pcap file name
2510
2511 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002512 Dictionary with wifi band as key and the tuple
2513 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002514 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002515 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002516 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002517 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002518 if wifi_band == 'dual':
2519 bands = [BAND_2G, BAND_5G]
2520 else:
2521 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002522 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002523 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002524 proc = pcap.start_packet_capture(band, log_dir, test_name)
2525 procs[band] = (proc, os.path.join(log_dir, test_name))
2526 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002527
Bindu Mahadevff295782019-02-08 16:17:48 -08002528
xianyuanjia0431ba32018-12-14 09:56:42 -08002529def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002530 """Stop packet capture in monitor mode.
2531
2532 Since, the pcap logs in monitor mode can be very large, we will
2533 delete them if they are not required. 'test_status' if True, will delete
2534 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002535
2536 Args:
2537 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002538 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002539 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002540 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002541 for proc, fname in procs.values():
2542 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002543
2544 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002545 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002546
Omar El Ayach8c017902020-10-18 10:26:57 -07002547
Jaineel95887fd2019-10-16 16:19:01 -07002548def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002549 """Verify that a mac address is not found in the captured packets.
2550
2551 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002552 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002553 mac: string representation of the mac address
2554 packets: packets obtained by rdpcap(pcap_fname)
2555 """
2556 for pkt in packets:
2557 logging.debug("Packet Summary = %s", pkt.summary())
2558 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002559 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2560 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002561
Omar El Ayach8c017902020-10-18 10:26:57 -07002562
Jaineel95887fd2019-10-16 16:19:01 -07002563def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002564 """Verify that a mac address is found in the captured packets.
2565
2566 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002567 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002568 mac: string representation of the mac address
2569 packets: packets obtained by rdpcap(pcap_fname)
2570 """
2571 for pkt in packets:
2572 if mac in pkt.summary():
2573 return
Jaineel95887fd2019-10-16 16:19:01 -07002574 asserts.fail("Did not find MAC = %s in packet sniffer."
2575 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002576
Omar El Ayach8c017902020-10-18 10:26:57 -07002577
Girish Moturuddc0d382020-08-24 12:08:41 -07002578def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002579 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002580 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002581
Bindu Mahadevff295782019-02-08 16:17:48 -08002582
Girish Moturuddc0d382020-08-24 12:08:41 -07002583def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002584 """Start cnss_diag to record extra wifi logs
2585
2586 Args:
2587 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002588 cnss_diag_file: cnss diag config file to push to device.
2589 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002590 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002591 if ad.model not in pixel_models:
2592 ad.log.info("Device not supported to collect pixel logger")
2593 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002594 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2595 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2596 else:
2597 prop = wifi_constants.CNSS_DIAG_PROP
2598 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002599 if not int(
2600 ad.adb.shell("ls -l %s%s | wc -l" %
2601 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002602 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002603 ad.adb.shell(
2604 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2605 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002606 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2607
Bindu Mahadevff295782019-02-08 16:17:48 -08002608
Girish Moturuddc0d382020-08-24 12:08:41 -07002609def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002610 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002611 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002612
Bindu Mahadevff295782019-02-08 16:17:48 -08002613
Girish Moturuddc0d382020-08-24 12:08:41 -07002614def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002615 """Stops cnss_diag
2616
2617 Args:
2618 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002619 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002620 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002621 if ad.model not in pixel_models:
2622 ad.log.info("Device not supported to collect pixel logger")
2623 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002624 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2625 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2626 else:
2627 prop = wifi_constants.CNSS_DIAG_PROP
2628 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2629
Bindu Mahadevff295782019-02-08 16:17:48 -08002630
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002631def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002632 """Pulls the cnss_diag logs in the wlan_logs dir
2633 Args:
2634 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002635 """
2636 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2637 if logs:
2638 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002639 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002640 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002641 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002642
Bindu Mahadevff295782019-02-08 16:17:48 -08002643
Omar El Ayach8c017902020-10-18 10:26:57 -07002644LinkProbeResult = namedtuple(
2645 'LinkProbeResult',
2646 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002647
2648
2649def send_link_probe(ad):
2650 """Sends a link probe to the currently connected AP, and returns whether the
2651 probe succeeded or not.
2652
2653 Args:
2654 ad: android device object
2655 Returns:
2656 LinkProbeResult namedtuple
2657 """
2658 stdout = ad.adb.shell('cmd wifi send-link-probe')
2659 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2660 'Exception while sending link probe: ' + stdout)
2661
2662 is_success = False
2663 elapsed_time = None
2664 failure_reason = None
2665 if 'succeeded' in stdout:
2666 is_success = True
2667 elapsed_time = next(
2668 (int(token) for token in stdout.split() if token.isdigit()), None)
2669 elif 'failed with reason' in stdout:
2670 failure_reason = next(
2671 (int(token) for token in stdout.split() if token.isdigit()), None)
2672 else:
2673 asserts.fail('Unexpected link probe result: ' + stdout)
2674
Omar El Ayach8c017902020-10-18 10:26:57 -07002675 return LinkProbeResult(is_success=is_success,
2676 stdout=stdout,
2677 elapsed_time=elapsed_time,
2678 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002679
2680
2681def send_link_probes(ad, num_probes, delay_sec):
2682 """Sends a sequence of link probes to the currently connected AP, and
2683 returns whether the probes succeeded or not.
2684
2685 Args:
2686 ad: android device object
2687 num_probes: number of probes to perform
2688 delay_sec: delay time between probes, in seconds
2689 Returns:
2690 List[LinkProbeResult] one LinkProbeResults for each probe
2691 """
2692 logging.info('Sending link probes')
2693 results = []
2694 for _ in range(num_probes):
2695 # send_link_probe() will also fail the test if it sees an exception
2696 # in the stdout of the adb shell command
2697 result = send_link_probe(ad)
2698 logging.info('link probe results: ' + str(result))
2699 results.append(result)
2700 time.sleep(delay_sec)
2701
2702 return results
2703
2704
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002705def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002706 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002707
2708 Args:
2709 test: the calling test class object.
2710 index: int, index of the AP.
2711 ap: access_point object of the AP.
2712 network: dict with information of the network, including ssid,
2713 password and bssid.
2714 bandwidth: the operation bandwidth for the AP, default 80MHz.
2715 channel: the channel number for the AP.
2716 Returns:
2717 brconfigs: the bridge interface configs
2718 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002719 bss_settings = []
2720 ssid = network[WifiEnums.SSID_KEY]
2721 test.access_points[index].close()
2722 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002723
Omar El Ayach8c017902020-10-18 10:26:57 -07002724 # Configure AP as required.
2725 if "password" in network.keys():
2726 password = network["password"]
2727 security = hostapd_security.Security(security_mode="wpa",
2728 password=password)
2729 else:
2730 security = hostapd_security.Security(security_mode=None, password=None)
2731 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2732 ssid=ssid,
2733 security=security,
2734 bss_settings=bss_settings,
2735 vht_bandwidth=bandwidth,
2736 profile_name='whirlwind',
2737 iface_wlan_2g=ap.wlan_2g,
2738 iface_wlan_5g=ap.wlan_5g)
2739 ap.start_ap(config)
2740 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002741
2742
2743def turn_ap_off(test, AP):
2744 """Bring down hostapd on the Access Point.
2745 Args:
2746 test: The test class object.
2747 AP: int, indicating which AP to turn OFF.
2748 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002749 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002750 if hostapd_2g.is_alive():
2751 hostapd_2g.stop()
2752 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002753 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002754 if hostapd_5g.is_alive():
2755 hostapd_5g.stop()
2756 logging.debug('Turned WLAN1 AP%d off' % AP)
2757
2758
2759def turn_ap_on(test, AP):
2760 """Bring up hostapd on the Access Point.
2761 Args:
2762 test: The test class object.
2763 AP: int, indicating which AP to turn ON.
2764 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002765 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002766 if not hostapd_2g.is_alive():
2767 hostapd_2g.start(hostapd_2g.config)
2768 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002769 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002770 if not hostapd_5g.is_alive():
2771 hostapd_5g.start(hostapd_5g.config)
2772 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002773
2774
2775def turn_location_off_and_scan_toggle_off(ad):
2776 """Turns off wifi location scans."""
2777 utils.set_location_service(ad, False)
2778 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2779 msg = "Failed to turn off location service's scan."
2780 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002781
2782
2783def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2784 """ Set SoftAP mode channel
2785
2786 Args:
2787 dut: android device object
2788 ap_iface: interface of SoftAP mode.
2789 cs_count: how many beacon frames before switch channel, default = 10
2790 channel: a wifi channel.
2791 """
2792 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002793 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002794 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002795 chan_switch_result = dut.adb.shell(
2796 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002797 if chan_switch_result == 'OK':
2798 dut.log.info('switch hotspot channel to {}'.format(channel))
2799 return chan_switch_result
2800
2801 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002802
2803def get_wlan0_link(dut):
2804 """ get wlan0 interface status"""
2805 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2806 out = dut.adb.shell(get_wlan0)
2807 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2808 asserts.assert_true("ssid" in out,
2809 "Client doesn't connect to any network")
Alfie Chenb3263dd2021-02-04 18:54:34 +08002810 return out
Girish Moturubea6c7e2021-05-07 16:24:27 -07002811
2812def verify_11ax_wifi_connection(ad, wifi6_supported_models, wifi6_ap):
2813 """Verify 11ax for wifi connection.
2814
2815 Args:
2816 ad: adndroid device object
2817 wifi6_supported_models: device supporting 11ax.
2818 wifi6_ap: if the AP supports 11ax.
2819 """
2820 if wifi6_ap and ad.model in wifi6_supported_models:
2821 logging.info("Verifying 11ax. Model: %s" % ad.model)
2822 asserts.assert_true(
2823 ad.droid.wifiGetConnectionStandard() ==
2824 wifi_constants.WIFI_STANDARD_11AX, "DUT did not connect to 11ax.")
2825
2826def verify_11ax_softap(dut, dut_client, wifi6_supported_models):
2827 """Verify 11ax SoftAp if devices support it.
2828
2829 Check if both DUT and DUT client supports 11ax, then SoftAp turns on
2830 with 11ax mode and DUT client can connect to it.
2831
2832 Args:
2833 dut: Softap device.
2834 dut_client: Client connecting to softap.
2835 wifi6_supported_models: List of device models supporting 11ax.
2836 """
2837 if dut.model in wifi6_supported_models and dut_client.model in wifi6_supported_models:
2838 logging.info(
2839 "Verifying 11ax softap. DUT model: %s, DUT Client model: %s",
2840 dut.model, dut_client.model)
2841 asserts.assert_true(
2842 dut_client.droid.wifiGetConnectionStandard() ==
2843 wifi_constants.WIFI_STANDARD_11AX,
2844 "DUT failed to start SoftAp in 11ax.")
“Alfie90ee7cb2021-04-20 23:16:12 +08002845
2846def check_available_channels_in_bands_2_5(dut, country_code):
2847 """Check if DUT is capable of enable BridgedAp.
2848 #TODO: Find a way to make this function flexible by taking an argument.
2849
2850 Args:
2851 country_code: country code, e.g., 'US', 'JP'.
2852 Returns:
2853 True: If DUT is capable of enable BridgedAp.
2854 False: If DUT is not capable of enable BridgedAp.
2855 """
2856 set_wifi_country_code(dut, country_code)
2857 country = dut.droid.wifiGetCountryCode()
2858 dut.log.info("DUT current country code : {}".format(country))
2859 # Wi-Fi ON and OFF to make sure country code take effet.
2860 wifi_toggle_state(dut, True)
2861 wifi_toggle_state(dut, False)
2862
2863 # Register SoftAp Callback and get SoftAp capability.
2864 callbackId = dut.droid.registerSoftApCallback()
2865 capability = get_current_softap_capability(dut, callbackId, True)
2866 dut.droid.unregisterSoftApCallback(callbackId)
2867
2868 if capability[wifi_constants.
2869 SOFTAP_CAPABILITY_24GHZ_SUPPORTED_CHANNEL_LIST] and \
2870 capability[wifi_constants.
2871 SOFTAP_CAPABILITY_5GHZ_SUPPORTED_CHANNEL_LIST]:
2872 return True
2873 return False
2874
2875
2876@retry(tries=5, delay=2)
2877def validate_ping_between_two_clients(dut1, dut2):
2878 """Make 2 DUT ping each other.
2879
2880 Args:
2881 dut1: An AndroidDevice object.
2882 dut2: An AndroidDevice object.
2883 """
2884 # Get DUTs' IPv4 addresses.
2885 dut1_ip = ""
2886 dut2_ip = ""
2887 try:
2888 dut1_ip = dut1.droid.connectivityGetIPv4Addresses('wlan0')[0]
2889 except IndexError as e:
2890 dut1.log.info(
2891 "{} has no Wi-Fi connection, cannot get IPv4 address."
2892 .format(dut1.serial))
2893 try:
2894 dut2_ip = dut2.droid.connectivityGetIPv4Addresses('wlan0')[0]
2895 except IndexError as e:
2896 dut2.log.info(
2897 "{} has no Wi-Fi connection, cannot get IPv4 address."
2898 .format(dut2.serial))
2899 # Test fail if not able to obtain two DUT's IPv4 addresses.
2900 asserts.assert_true(dut1_ip and dut2_ip,
2901 "Ping failed because no DUT's IPv4 address")
2902
2903 dut1.log.info("{} IPv4 addresses : {}".format(dut1.serial, dut1_ip))
2904 dut2.log.info("{} IPv4 addresses : {}".format(dut2.serial, dut2_ip))
2905
2906 # Two clients ping each other
2907 dut1.log.info("{} ping {}".format(dut1_ip, dut2_ip))
2908 asserts.assert_true(
2909 utils.adb_shell_ping(dut1, count=10, dest_ip=dut2_ip,
2910 timeout=20),
2911 "%s ping %s failed" % (dut1.serial, dut2_ip))
2912
2913 dut2.log.info("{} ping {}".format(dut2_ip, dut1_ip))
2914 asserts.assert_true(
2915 utils.adb_shell_ping(dut2, count=10, dest_ip=dut1_ip,
2916 timeout=20),
2917 "%s ping %s failed" % (dut2.serial, dut1_ip))
2918